
Tests des slices (couches spécifiques) de l'application
Découvrez les tests de slices dans Spring Boot (@WebMvcTest, @DataJpaTest, etc.) pour tester des couches spécifiques de votre application de manière isolée, rapide et efficace.
Comprendre les tests de slices : isoler pour mieux tester
Dans une application Spring Boot typique, différentes couches collaborent : contrôleurs web, services métier, repositories de données, etc. Tester l'application entière avec @SpringBootTest est utile pour les tests d'intégration globaux, mais cela peut être lent et rendre difficile l'identification des erreurs spécifiques à une couche. Les tests de slices (ou tests de tranches) offrent une approche alternative et complémentaire.
Le principe fondamental d'un test de slice est de ne charger et configurer qu'une partie spécifique (une "slice" ou "tranche") du contexte d'application Spring. Au lieu de démarrer tous les beans, seules les configurations et les composants pertinents pour la couche testée sont initialisés. Par exemple, pour tester un contrôleur web, on ne chargera que la couche web (contrôleurs, convertisseurs, gestionnaires d'exceptions liés à MVC), sans initialiser la couche de persistance ou les services métier non directement requis.
Cette approche ciblée apporte des avantages significatifs :
- Rapidité : Charger un contexte partiel est beaucoup plus rapide que charger l'application entière, ce qui accélère considérablement le cycle de feedback pendant le développement.
- Isolation : En se concentrant sur une seule couche, les tests sont moins susceptibles d'échouer à cause de problèmes dans d'autres parties non liées de l'application. Le débogage devient plus simple.
- Focus : Les tests sont plus précis et vérifient spécifiquement le comportement de la couche ciblée (par exemple, le mapping des requêtes HTTP dans un contrôleur, la logique de requête dans un repository).
- Moins de configuration : Les annotations de slice test fournissent souvent des configurations par défaut adaptées (comme une base de données en mémoire pour les tests de persistance) et des outils d'aide spécifiques (comme
MockMvcpour les tests web).
Spring Boot fournit plusieurs annotations dédiées pour faciliter la création de ces tests de slices.
Panorama des principales annotations de tests de slices
Spring Boot propose un éventail d'annotations, chacune ciblant une couche ou une fonctionnalité spécifique. Voici les plus couramment utilisées :
@WebMvcTest: Conçue pour tester la couche Spring MVC (contrôleurs@Controller,@RestController, configurations@ControllerAdvice, filtres, etc.). Elle ne charge pas les beans@Service,@Repositoryou@Componentpar défaut. Elle auto-configureMockMvc, un outil puissant pour simuler des requêtes HTTP et vérifier les réponses sans démarrer de serveur web réel. C'est idéal pour tester le mapping des requêtes, la validation des entrées, la sérialisation/désérialisation et la gestion des vues ou des réponses REST.@WebFluxTest: L'équivalent de@WebMvcTestpour les applications utilisant le stack réactif Spring WebFlux. Elle auto-configureWebTestClientpour tester les endpoints réactifs.@DataJpaTest: Cible la couche de persistance JPA. Elle scanne les entités@Entityet configure les repositories Spring Data JPA (interfaces héritant deJpaRepository). Par défaut, elle configure une base de données H2 en mémoire, exécute chaque test dans une transaction annulée (rollback) et fournit un beanTestEntityManagerpour faciliter la manipulation des entités dans les tests.@DataJdbcTest: Similaire à@DataJpaTest, mais pour les applications utilisant Spring Data JDBC. Elle configure une base de données en mémoire, les repositories JDBC et fournit unJdbcTemplate.@DataMongoTest: Pour tester la couche de persistance avec MongoDB. Elle scanne les documents@Document, configure les repositories MongoDB et fournit unMongoTemplate. Elle peut utiliser une base MongoDB embarquée ou se connecter à une instance existante. Notez qu'elle n'est pas transactionnelle par défaut.@RestClientTest: Permet de tester les clients HTTP basés surRestTemplateouWebClient. Elle ne charge pas l'application serveur mais fournit un serveur mock (MockRestServiceServerpourRestTemplateou des outils similaires pourWebClient) pour simuler les réponses des services externes que votre client appelle.@JsonTest: Spécialisée dans le test de la sérialisation et désérialisation JSON. Elle auto-configure des utilitaires commeJacksonTester,GsonTester, etc., permettant de vérifier précisément comment les objets Java sont convertis en JSON et vice-versa, indépendamment des couches web ou de persistance.
Chacune de ces annotations applique une auto-configuration ciblée et limite l'analyse des composants aux éléments pertinents pour la slice testée, garantissant ainsi rapidité et isolation.
Choisir la bonne stratégie : tests de slices vs @SpringBootTest
Il est essentiel de comprendre quand utiliser un test de slice et quand un test d'intégration complet avec @SpringBootTest est plus approprié. Ce n'est pas une question de choisir l'un ou l'autre, mais plutôt d'utiliser la bonne approche pour le bon objectif afin de construire une suite de tests robuste et efficace.
Utilisez les tests de slices lorsque :
- Vous voulez tester une couche spécifique en isolation (par exemple, vérifier uniquement le comportement d'un contrôleur, d'un repository ou la sérialisation JSON).
- La rapidité d'exécution est une priorité (fréquent pendant le développement actif pour un feedback rapide).
- Vous voulez tester une interaction simple au sein d'une même couche (par exemple, un contrôleur appelant un convertisseur qu'il utilise).
- Vous voulez vous assurer qu'un composant spécifique (comme un repository) fonctionne correctement avec la technologie sous-jacente (JPA, JDBC, MongoDB) sans vous soucier des couches supérieures.
Utilisez @SpringBootTest lorsque :
- Vous devez tester l'interaction entre plusieurs couches (par exemple, un flux complet depuis une requête HTTP reçue par un contrôleur, traitée par un service et persistant des données via un repository).
- Vous voulez vérifier que la configuration globale de l'application est correcte et que les beans s'injectent et collaborent comme prévu dans un contexte complet.
- Vous effectuez des tests end-to-end (par exemple, en démarrant un vrai serveur sur un port aléatoire avec
webEnvironment = WebEnvironment.RANDOM_PORTet en utilisantTestRestTemplateouWebTestClientpour envoyer de vraies requêtes HTTP). - Vous testez des aspects qui dépendent du démarrage complet de l'application (comme des tâches planifiées
@Scheduledou des listeners d'événements applicatifs).
Il est souvent judicieux de combiner ces approches. Par exemple, tester finement les méthodes d'un repository avec @DataJpaTest, tester les endpoints d'un contrôleur et ses mappings avec @WebMvcTest (en utilisant @MockBean pour simuler les services dépendants), puis avoir quelques tests @SpringBootTest pour valider les flux critiques de bout en bout. Cette pyramide de tests (beaucoup de tests unitaires et de slices rapides, moins de tests d'intégration plus lents) offre un bon compromis entre couverture, rapidité et maintenabilité.
Même au sein d'un test de slice, vous pouvez avoir besoin d'inclure des beans spécifiques non chargés par défaut (via @Import) ou de remplacer des dépendances par des mocks (via @MockBean), offrant une flexibilité pour affiner le périmètre exact de votre test.