Beim Erstellen einer neuen Web-API mit PJ habe ich überprüft, welche Art von Test mit Junit erstellt werden kann. Notieren Sie sich dies.
Fügen Sie einen Mock mit Mockito ein, ohne von anderen Klassen abhängig zu sein. Das Testen ist möglich, ohne auf die Implementierung anderer Klassen zu warten.
EmployeeControllerSliceTest
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import com.example.demo.domain.Employee;
import com.example.demo.usecase.GetEmployeeUsecase;
@WebMvcTest(EmployeeController.class)
class EmployeeControllerSliceTest {
/**Mock, um in das Testziel zu injizieren*/
@MockBean
GetEmployeeUsecase mockedUsecase;
/**Client für Verbindungstest*/
@Autowired
private MockMvc mvc;
@Test
void testGetOne() throws Exception {
//Scheinbewegung einstellen
when(this.mockedUsecase.getEmployee(anyString())).thenReturn(Optional.ofNullable(new Employee("foo", "bar")));
//Führen Sie den Test aus
this.mvc.perform(get("/employees/{employeeId}", "123")) //
.andExpect(status().is(200)) //
.andExpect(content().json("{\"employeeId\":\"foo\",\"name\":\"bar\"}")); //Verspotten Sie Daten unabhängig von der Abfrage
}
}
Referenz Auto-configured Spring MVC Tests Mocking and Spying Beans
Kann getestet werden, indem die Abhängigkeit von anderen Klassen explizit deklariert wird.
EmployeeControllerSliceAndImportTest
package com.example.demo.presentation;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.web.servlet.MockMvc;
import com.example.demo.infrastructure.TempEmployeeRepositoryImp;
import com.example.demo.usecase.GetEmployeeUsecase;
@WebMvcTest(EmployeeController.class)
@Import({ GetEmployeeUsecase.class, TempEmployeeRepositoryImp.class })
class EmployeeControllerSliceAndImportTest {
/**Client für Verbindungstest*/
@Autowired
private MockMvc mvc;
@Test
void testGetOne() throws Exception {
//Lauf
this.mvc.perform(get("/employees/{employeeId}", "123")) //
//Bestätigung
.andExpect(status().is(200)) //
.andExpect(content().json("{\"employeeId\":\"123\",\"name\":\"Taro\"}")); //Daten aus dem Repository erhalten
}
}
Referenz Auto-configured Spring MVC Tests
Lokale Tests sind in einer Umgebung möglich, die fast der beim Starten des eigentlichen Servers entspricht.
EmployeeControllerOnLocalhostTest
package com.example.demo.presentation;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.reactive.server.WebTestClient;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class EmployeeControllerOnLocalhostTest {
/**Client für Verbindungstest*/
WebTestClient client = WebTestClient.bindToServer().build();
/**Verbindungsziel-Portnummer*/
@LocalServerPort
private int port;
@Test
void test() throws Exception {
//Lauf
this.client.get().uri("http://localhost:" + this.port + "/employees/{employeeId}", "123").exchange() //
//Bestätigung
.expectStatus().isEqualTo(HttpStatus.valueOf(200)) //
.expectBody(String.class).isEqualTo("{\"employeeId\":\"123\",\"name\":\"Taro\"}");
}
}
Referenz Testing with a running server WebTestClient Spring WebClient Requests with Parameters
Sie können eine Verbindung zu jedem laufenden Server herstellen und dessen Verhalten testen. Der Server muss separat gestartet werden, bevor der Junit-Test ausgeführt wird. Umgekehrt können Sie jeden laufenden Web-API-Server testen. Es muss nicht Java sein.
EmployeeControllerOnExternalServerTest
package com.example.demo.presentation;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.reactive.server.WebTestClient;
class EmployeeControllerOnExternalServerTest {
/**Client für Verbindungstest*/
WebTestClient client = WebTestClient.bindToServer().build();
/**Verbindungsziel-Portnummer*/
private final int port = 8080;
@Test
void test() throws Exception {
//Lauf
this.client.get().uri("http://localhost:" + this.port + "/employees/{employeeId}", "123").exchange() //
//Bestätigung
.expectStatus().isEqualTo(HttpStatus.valueOf(200)) //
.expectBody(String.class).isEqualTo("{\"employeeId\":\"123\",\"name\":\"Taro\"}");
}
}
Referenz WebTestClient Spring WebClient Requests with Parameters
EmployeeController.java
EmployeeController
package com.example.demo.presentation;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.domain.Employee;
import com.example.demo.usecase.GetEmployeeUsecase;
@RestController
public class EmployeeController {
@Autowired
GetEmployeeUsecase getUsecase;
@GetMapping("/employees/{employeeId}")
Optional<Employee> getOne(@PathVariable final String employeeId) {
return this.getUsecase.getEmployee(employeeId);
}
}
GetEmployeeUsecase.java
GetEmployeeUsecase
package com.example.demo.usecase;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.domain.Employee;
import com.example.demo.domain.EmployeeRepository;
@Service
public class GetEmployeeUsecase {
@Autowired
EmployeeRepository repository;
public Optional<Employee> getEmployee(final String employeeId) {
return this.repository.findOneById(employeeId);
}
}
Employee.java
Employee
package com.example.demo.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class Employee {
private String employeeId = null;
private String name = null;
@SuppressWarnings("unused")
private Employee() {
}
}
EmployeeRepository.java
EmployeeRepository
package com.example.demo.domain;
import java.util.Optional;
import org.springframework.stereotype.Repository;
public interface EmployeeRepository {
Optional<Employee> findOneById(String employeeId);
}
TempEmployeeRepositoryImp.java
TempEmployeeRepositoryImp
package com.example.demo.infrastructure;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Repository;
import com.example.demo.domain.Employee;
import com.example.demo.domain.EmployeeRepository;
@Repository
public class TempEmployeeRepositoryImp implements EmployeeRepository {
private final List<Employee> db;
public TempEmployeeRepositoryImp() {
this.db = new ArrayList<>();
//Als Ausgangsdaten
this.db.add(new Employee("123", "Taro"));
}
@Override
public Optional<Employee> findOneById(final String employeeId) {
return this.db.stream().filter(e -> e.getEmployeeId().equals(employeeId)).findFirst();
}
}
GitHub https://github.com/tmtmra/restControllerTestSample
Ich bin ein Anfänger, der vor einem Jahr mit dem Programmieren begonnen hat. Bitte geben Sie mir verschiedene Meinungen und Ratschläge.
Recommended Posts