🖨️ Version PDF
But : tester une classe isolée sans démarrer le contexte Spring.
Mockito
Pour les exemples de codes, je reprends souvent le TP Waouf Waouf. Dans le code ci-dessous, je ne teste pas les routes HTTP.
import org.junit.jupiter.api.Test; import org.mockito.Mockito; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; class PublicControllerTest { @Test void testGetAllChiens() { // Mocks ChienRepository mockRepo = Mockito.mock(ChienRepository.class); Mockito.when(mockRepo.findAll()).thenReturn(List.of(new Chien("Rex"))); // Injection manuelle dans le contrôleur PublicController controller = new PublicQueryController(mockRepo, null); // Exécution et vérification List<Chien> result = controller.getAllChiens(); assertThat(result).hasSize(1); assertThat(result.get(0).getNom()).isEqualTo("Rex"); } }
But : tester le contrôleur via des requêtes HTTP simulées.
Dans ce code ci-dessous, je teste toute la couche Web (controllers, mappings, JSON), ce qui est plutôt rapide car Spring ne charge pas tout le contexte !
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; @WebMvcTest(PublicController.class) class PublicControllerIntegrationTest { @Autowired private MockMvc mockMvc; @MockBean private ChienRepository chienRepository; @Test void shouldReturnListOfChiens() throws Exception { when(chienRepository.findAll()).thenReturn(List.of(new Chien("Milou"))); mockMvc.perform(get("/api/public/chiens")) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].nom").value("Milou")); } }
But : tester l’application entière (Web + Service + Repository + DB).
C’est l’équivalent d’un test avec un vrai serveur (Tomcat embarqué), c’est plus lent (quelques secondes), mais bon… c’est pratique !
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class ApplicationIntegrationTest { @Autowired private TestRestTemplate restTemplate; @Test void shouldReturnStatus200() { ResponseEntity<String> response = restTemplate.getForEntity("/api/public/chiens", String.class); assertThat(response.getStatusCode().value()).isEqualTo(200); } }
@WebMvcTest
@SpringBootTest
shouldReturn404WhenAdherentNotFound()
src/ ├── main/java/... pour le code principal └── test/java/... pour les tests unitaires et d'intégration ├── controller/ ├── service/ ├── repository/ └── ApplicationIntegrationTest.java
Voici un tableau d’une lite d’outils qui permettent de tout tester, du simple service au comportement complet d’une application dans un environnement réaliste.
@Test
@BeforeEach
@Nested
Mockito.mock()
when(...).thenReturn(...)
assertThat(result).hasSize(3).contains("Rex");
mockMvc.perform(get("/api/chiens"))
assertThat(value, is(notNullValue()))
@Testcontainers
@Container
stubFor(get("/api/externe").willReturn(okJson(...)))
L’idéal est d’utiliser PostgreSQL ou MySQL en PROD et H2 ou Testcontainers en TEST selon le niveau d’intégration.
spring.datasource.url=jdbc:h2:mem:testdb
@Container PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");
En voici quelques uns, il y en a beaucoup, personnellement, j’utilise Eclemma que j’explique dans un autre cours depuis la page d’accueil.
Eclemma
De toutes façons, certains sont déjà présents dans les IDE comme IntelliJ et GitLab CI/CD.
Nous abordons ces outils dans le cours DevOps, mais je les liste pour info.
.gitlab-ci.yml
docker-compose up
mvnw
./mvnw test
gradlew
./gradlew test
Exemple des dépendances ajoutées pour Spring Boot dans le fichier build.gradle ou pom.xml selon vos préférences.
build.gradle
pom.xml
Pour intégrer :
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.mockito:mockito-core' testImplementation 'org.assertj:assertj-core' testImplementation 'org.testcontainers:junit-jupiter' testImplementation 'org.testcontainers:postgresql'