Lors de la création d'une nouvelle API Web avec PJ, j'ai vérifié quel type de test peut être créé avec Junit, alors prenez note.
Insérez une maquette avec mockito sans dépendre des autres classes. Le test est possible sans attendre l'implémentation d'autres classes.
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 pour injecter dans la cible de test*/
@MockBean
GetEmployeeUsecase mockedUsecase;
/**Client pour le test de connexion*/
@Autowired
private MockMvc mvc;
@Test
void testGetOne() throws Exception {
//Définir un mouvement simulé
when(this.mockedUsecase.getEmployee(anyString())).thenReturn(Optional.ofNullable(new Employee("foo", "bar")));
//Lancer le test
this.mvc.perform(get("/employees/{employeeId}", "123")) //
.andExpect(status().is(200)) //
.andExpect(content().json("{\"employeeId\":\"foo\",\"name\":\"bar\"}")); //Mock data indépendamment de la requête
}
}
référence Auto-configured Spring MVC Tests Mocking and Spying Beans
Peut être testé en déclarant explicitement la dépendance à d'autres classes.
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 pour le test de connexion*/
@Autowired
private MockMvc mvc;
@Test
void testGetOne() throws Exception {
//Courir
this.mvc.perform(get("/employees/{employeeId}", "123")) //
//Vérification
.andExpect(status().is(200)) //
.andExpect(content().json("{\"employeeId\":\"123\",\"name\":\"Taro\"}")); //Données obtenues à partir du référentiel
}
}
référence Auto-configured Spring MVC Tests
Le test local est possible dans un environnement qui est presque le même que lorsque le serveur réel est démarré.
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 pour le test de connexion*/
WebTestClient client = WebTestClient.bindToServer().build();
/**Numéro de port de destination de la connexion*/
@LocalServerPort
private int port;
@Test
void test() throws Exception {
//Courir
this.client.get().uri("http://localhost:" + this.port + "/employees/{employeeId}", "123").exchange() //
//Vérification
.expectStatus().isEqualTo(HttpStatus.valueOf(200)) //
.expectBody(String.class).isEqualTo("{\"employeeId\":\"123\",\"name\":\"Taro\"}");
}
}
référence Testing with a running server WebTestClient Spring WebClient Requests with Parameters
Vous pouvez vous connecter à n'importe quel serveur en cours d'exécution et tester son comportement. Il est nécessaire de démarrer le serveur séparément avant d'exécuter le test Junit. Inversement, vous pouvez tester n'importe quel serveur d'API Web en cours d'exécution. Il n'est pas nécessaire que ce soit Java.
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 pour le test de connexion*/
WebTestClient client = WebTestClient.bindToServer().build();
/**Numéro de port de destination de la connexion*/
private final int port = 8080;
@Test
void test() throws Exception {
//Courir
this.client.get().uri("http://localhost:" + this.port + "/employees/{employeeId}", "123").exchange() //
//Vérification
.expectStatus().isEqualTo(HttpStatus.valueOf(200)) //
.expectBody(String.class).isEqualTo("{\"employeeId\":\"123\",\"name\":\"Taro\"}");
}
}
référence 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<>();
//Comme données initiales
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
Je suis un débutant qui a commencé à programmer il y a un an, alors n'hésitez pas à me donner divers avis et conseils.
Recommended Posts