web-dev-qa-db-fra.com

Comment exclure les classes de * 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 qu'actuellement cela ne nuit pas au test, j'aimerais désactiver les modules inutiles pendant les tests unitaires pour accélérer et éviter les conflits potentiels.

50
Hendy Irawan

Les meilleures réponses ne suggèrent pas une solution encore plus simple et plus flexible.

il suffit de placer un 

@TestPropertySource(properties=
{"spring.autoconfigure.exclude=comma.seperated.ClassNames,com.example.FooAutoConfiguration"})
@SpringBootTest
public class MySpringTest {...}

annotation au-dessus de votre classe de test. Cela signifie que les autres tests ne sont pas affectés par le cas particulier du test actuel. Si une configuration affecte la plupart de vos tests, envisagez d'utiliser le profil Spring comme le suggère la réponse actuelle.

Merci à @skirsch de m'avoir encouragé à passer d'un commentaire à une réponse.

3
coderatchet

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

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

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

Dans un cas d'utilisation similaire, je souhaitais tester un référentiel configuré avec Spring Boot de manière isolée (dans mon cas, la configuration automatique de Spring Security é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 démarrez un conteneur de servlet intégré entièrement configuré.

Cependant, comme vous, je ne pouvais pas comprendre comment vous deviez configurer le test pour ne tester que la couche de référentiel à l'aide du point d'entrée de configuration principal, à savoir en utilisant votre approche de @SpringApplicationConfiguration(classes = Application.class).

Ma solution consistait à créer un contexte d'application entièrement nouveau, exclusif aux tests. Donc, dans src/test/Java, j'ai deux fichiers dans un sous-paquet nommé 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 évité des ennuis, mais il serait très utile que quelqu'un de l'équipe Spring Boot puisse proposer une solution alternative recommandée.

27
Matt C

J'avais un problème similaire mais je suis arrivé à une solution différente qui pourrait aider les autres. J'ai utilisé Spring Profiles pour séparer les classes de test et de configuration d'applications. 

  1. Créez une classe TestConfig avec un profil spécifique et excluez toute configuration d'application de l'analyse de composant que vous souhaitez ici.

  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{ ... }
11
Stuart

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. Le fait est que vous avez déjà une annotation @EnableAutoConfiguration dans la classe Application qui n'exclut pas la CrshAutoConfiguration.Spring utilise cette annotation plutôt que celle de votre classe de test pour effectuer la configuration automatique de vos beans. 

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

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

6

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 sélectionnée que lors des tests d'intégration spécifiques qui en ont besoin, car d'autres configurations de test effectuent une analyse de composant différente.

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 {

}
6
James McShane
@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

4
Kingson wu

eu le même genre de problème, n'a pas été en mesure d'exclure la classe de démarrage principale de printemps lors des tests. Résolu en utilisant l'approche suivante.

Au lieu d'utiliser @SpringBootApplication, utilisez les trois annotations qu'il contient et attribuez 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 le balayage automatique pour les annotations de configuration ...

2
myroch

Je pense que la meilleure solution actuellement pour springBoot 2.0 consiste à utiliser des profils.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.DEFINED_PORT)
@ActiveProfiles("test")
public class ExcludeAutoConfigIntegrationTest {
    // ...
} 

spring.autoconfigure.exclude = org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration

quoi qu'il en soit, dans le lien suivant , donnez 6 alternatives différentes pour résoudre ce problème.

1
oriaj

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

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

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

  1. Avec la configuration normale:

    @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 test personnalisée:

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

Si vous rencontrez ce problème avec Spring Boot 1.4.x et versions supérieures, 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

0
Tom Saleeba

Je me suis battu avec un problème similaire pendant un jour ... Mon scénario:

J'ai une application SpringBoot et j'utilise applicationContext.xml dans scr/main/resources pour configurer tous mes beans Spring. Pour tester (tests d'intégration), j'utilise un autre applicationContext.xml dans test/resources et tout fonctionne comme prévu: Spring/SpringBoot remplacerait applicationContext.xml à partir de scr/main/resources et utiliserais celui utilisé pour les tests. qui contenait les haricots configurés pour les tests.

Cependant, juste pour un UnitTest, je voulais encore une personnalisation pour le applicationContext.xml utilisé dans Testing, juste pour ce test, je voulais utiliser des haricots mockito, pour pouvoir mock et verify, et voici a commencé ma tête -mal!

Le problème est que Spring/SpringBoot ne substitue pas le applicationContext.xml de scr/main/resources UNIQUEMENT SI le fichier de test/resources A LE MÊME NOM . J'ai essayé pendant des heures d'utiliser quelque chose du genre:

@RunWith(SpringJUnit4ClassRunner.class)
@OverrideAutoConfiguration(enabled=true)
@ContextConfiguration({"classpath:applicationContext-test.xml"})

cela ne fonctionnait pas, Spring chargeait d’abord les beans de applicationContext.xml dans scr/main/resources

Ma solution basée sur les réponses ici par @ myroch et @Stuart:

  1. Définissez la configuration principale de l'application:

    @Configuration @ImportResource({"classpath:applicationContext.xml"}) public class MainAppConfig { }

ceci est utilisé dans l'application

@SpringBootApplication
@Import(MainAppConfig.class)
public class SuppressionMain implements CommandLineRunner
  1. Définir une configuration de test pour le test où vous souhaitez exclure la configuration principale

    @ComponentScan ( BasePackages = "com.mypackage", ExcludeFilters = { @ ComponentScan.Filter (type = ASSIGNABLE_TYPE, Value = {MainAppConfig.class}) }) . @ EnableAutoConfiguration Public class TestConfig {}

Ce faisant, Spring ne chargera pas applicationContext.xml et ne chargera que la configuration personnalisée spécifique à ce test.

0
razvang