Comment exclure les classes * AutoConfiguration dans les tests Spring Boot JUnit?

J’ai essayé:

@RunWith(SpringJUnit4ClassRunner.class) @EnableAutoConfiguration(exclude=CrshAutoConfiguration.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class LikeControllerTest { 

Cependant, le CRaSSHD démarre toujours. Bien que cela ne nuise pas actuellement au test, j’aimerais désactiver les modules inutiles lors des tests unitaires pour accélérer et éviter les conflits potentiels.

J’ai eu un cas d’utilisation similaire où je voulais tester un référentiel configuré par Spring Boot de manière isolée (dans mon cas, sans la configuration automatique de Spring Security qui échouait à mon test). @SpringApplicationConfiguration utilise SpringApplicationContextLoader et possède un JavaDoc indiquant

Peut être utilisé pour tester des fonctionnalités non Web (comme une couche de référentiel) ou pour démarrer un conteneur de servlets intégré entièrement configuré.

Cependant, comme vous, je n’ai pas pu déterminer comment configurer le test pour tester uniquement la couche de référentiel à l’aide du point d’entrée de configuration principal, c’est-à-dire en utilisant votre approche de @SpringApplicationConfiguration(classes = Application.class) .

Ma solution était de créer un tout nouveau contexte d’application exclusif pour les tests. Donc, dans src / test / java, j’ai deux fichiers dans un sous-paquet appelé repo

  1. RepoIntegrationTest.java
  2. TestRepoConfig.java

RepoIntegrationTest.java a

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TestRepoConfig.class) public class RepoIntegrationTest { 

et TestRepoConfig.java a

 @SpringBootApplication(exclude = SecurityAutoConfiguration.class) public class TestRepoConfig { 

Cela m’a permis de sortir du pésortingn mais ce serait vraiment utile si quelqu’un de l’équipe Spring Boot pouvait fournir une solution alternative recommandée

Un autre moyen simple d’exclure les classes de configuration automatique,

Ajouter ci-dessous une configuration similaire à votre fichier application.yml ,

 --- spring: profiles: test autoconfigure.exclude: org.springframework.boot.autoconfigure.session.SessionAutoConfiguration 

J’ai eu un problème similaire mais je suis arrivé à une solution différente qui pourrait aider les autres. J’ai utilisé des profils Spring pour séparer les classes de configuration de test et d’application.

  1. Créez une classe TestConfig avec un profil spécifique et excluez toute configuration d’application de l’parsing des composants souhaitée.

  2. Dans votre classe de test, définissez le profil pour qu’il corresponde à TestConfig et incluez-le à l’aide de l’annotation @ContextConfiguration.

Par exemple:

configuration:

 @Profile("test") @Configuration @EnableWebMvc @ComponentScan( basePackages="your.base.package", excludeFilters = { @Filter(type = ASSIGNABLE_TYPE, value = { ExcludedAppConfig1.class, ExcludedAppConfig2.class }) }) public class TestConfig { ...} 

tester:

 @ActiveProfiles("test") @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = TestConfig.class) @WebAppConfiguration public class SomeTest{ ... } 

Avec la nouvelle annotation @SpringBootTest , j’ai pris cette réponse et l’ai modifiée pour utiliser des profils avec une classe de configuration @SpringBootApplication . L’annotation @Profile est nécessaire pour que cette classe ne soit @Profile que lors des tests d’intégration spécifiques qui en ont besoin, car d’autres configurations de test effectuent des parsings de composants différentes.

Voici la classe de configuration:

 @Profile("specific-profile") @SpringBootApplication(scanBasePackages={"com.myco.package1", "com.myco.package2"}) public class SpecificTestConfig { } 

Ensuite, la classe de test référence cette classe de configuration:

 @RunWith(SpringRunner.class) @SpringBootTest(classes = { SpecificTestConfig.class }) @ActiveProfiles({"specific-profile"}) public class MyTest { } 

Je pense que l’utilisation de l’annotation @EnableAutoConfiguration sur une classe de test ne fonctionnera pas si vous utilisez @SpringApplicationConfiguration pour charger votre classe Application . La chose est que vous avez déjà une annotation @EnableAutoConfiguration dans la classe Application qui n’exclut pas la CrshAutoConfiguration . Spring utilise cette annotation au lieu de celle de votre classe de test pour effectuer la configuration automatique de vos beans.

Je pense que votre meilleur pari est d’utiliser un contexte d’application différent pour vos tests et d’exclure la CrshAutoConfiguration dans cette classe.

J’ai fait quelques tests et il semble que @EnableAutoConfiguration sur la classe de test soit complètement ignoré si vous utilisez l’annotation @SpringApplicationConfiguration et le SpringJUnit4ClassRunner .

eu le même genre de problème, n’a pas été en mesure d’exclure la classe de démarrage au spring principal pendant les tests. Résolu en utilisant l’approche suivante.

Au lieu d’utiliser @SpringBootApplication, utilisez les trois annotations qu’il contient et atsortingbuez-lui le nom @Configuration

 @Configuration("myApp") @EnableAutoConfiguration @ComponentScan public class MyApp { .. } 

Dans votre classe de test, définissez la configuration avec exactement le même nom:

 @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration // ugly hack how to exclude main configuration @Configuration("myApp") @SpringApplicationConfiguration(classes = MyTest.class) public class MyTest { ... } 

Cela devrait aider. Ce serait bien d’avoir un meilleur moyen de désactiver l’parsing automatique pour les annotations de configuration …

 @SpringBootTest(classes = {Application.class} , webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT , properties="spring.autoconfigure.exclude=com.xx.xx.AutoConfiguration" ) 

ref: https://github.com/spring-projects/spring-boot/issues/8579

J’ai également eu du mal avec cela et j’ai trouvé un modèle simple pour isoler le contexte de test après une lecture rapide des documents @ComponentScan .

/ **
* Une alternative sûre à {@link #basePackages} pour spécifier les paquets
* rechercher des composants annotés. Le package de chaque classe spécifiée sera analysé.
* Envisagez de créer une classe ou une interface spéciale de marqueur no-op dans chaque package
* qui ne sert à rien d’autre que d’être référencé par cet atsortingbut.
* /
Class[] basePackageClasses() default {};

  1. Créez un package pour vos tests printaniers ("com.example.test") .
  2. Créez une interface de marqueur dans le package en tant que qualificateur de contexte.
  3. Fournissez la référence d’interface de marqueur en tant que paramètre à basePackageClasses.

Exemple


IsolatedTest.java

 package com.example.test; @RunWith(SpringJUnit4ClassRunner.class) @ComponentScan(basePackageClasses = {TestDomain.class}) @SpringApplicationConfiguration(classes = IsolatedTest.Config.class) public class IsolatedTest { Ssortingng expected = "Read the documentation on @ComponentScan"; Ssortingng actual = "Too lazy when I can just search on Stack Overflow."; @Test public void testSomething() throws Exception { assertEquals(expected, actual); } @ComponentScan(basePackageClasses = {TestDomain.class}) public static class Config { public static void main(Ssortingng[] args) { SpringApplication.run(Config.class, args); } } } ... 

TestDomain.java

 package com.example.test; public interface TestDomain { //noop marker } 

Si vous rencontrez ce problème avec Spring Boot 1.4.x et supérieur, vous pourrez peut-être utiliser @OverrideAutoConfiguration(enabled=true) pour résoudre le problème.

Semblable à ce qui a été demandé / répondu ici https://stackoverflow.com/a/39253304/1410035

Si le problème est que votre SpringBootApplication / Configuration que vous importez est un composant analysant le package dans lequel se trouvent vos configurations de test, vous pouvez supprimer l’annotation @Configuration des configurations de test et vous pouvez toujours les utiliser dans les annotations @SpringBootTest. Par exemple, si vous avez une classe Application qui est votre configuration principale et une classe TestConfiguration qui est une configuration pour certains tests, mais pas tous, vous pouvez configurer vos classes comme suit:

 @Import(Application.class) //or the specific configurations you want //(Optional) Other Annotations that will not sortinggger an autowire public class TestConfiguration { //your custom test configuration } 

Et puis vous pouvez configurer vos tests de deux manières:

  1. Avec la configuration régulière:

     @SpringBootTest(classes = {Application.class}) //won't component scan your configuration because it doesn't have an autowire-able annotation //Other annotations here public class TestThatUsesNormalApplication { //my test code } 
  2. Avec la configuration de test personnalisée de test:

     @SpringBootTest(classes = {TestConfiguration.class}) //this still works! //Other annotations here public class TestThatUsesCustomTestConfiguration { //my test code }