Comment utiliser @ComponentScan avec test spécifique ContextConfigurations dans SpringJunit4TestRunner?
Je suis en train de tester un Ressort de Démarrage de l'application. J'ai test de plusieurs classes, dont chacune a besoin d'un ensemble différent de moqués ou autrement personnalisés haricots.
Voici un croquis de l'installation:
src/main/java:
package com.example.myapp;
@SpringBootApplication
@ComponentScan(
basePackageClasses = {
MyApplication.class,
ImportantConfigurationFromSomeLibrary.class,
ImportantConfigurationFromAnotherLibrary.class})
@EnableFeignClients
@EnableHystrix
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
package com.example.myapp.feature1;
@Component
public class Component1 {
@Autowired
ServiceClient serviceClient;
@Autowired
SpringDataJpaRepository dbRepository;
@Autowired
ThingFromSomeLibrary importantThingIDontWantToExplicitlyConstructInTests;
//methods I want to test...
}
src/test/java:
package com.example.myapp;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class Component1TestWithFakeCommunication {
@Autowired
Component1 component1; //<-- the thing we're testing. wants the above mock implementations of beans wired into it.
@Autowired
ServiceClient mockedServiceClient;
@Configuration
static class ContextConfiguration {
@Bean
@Primary
public ServiceClient mockedServiceClient() {
return mock(ServiceClient.class);
}
}
@Before
public void setup() {
reset(mockedServiceClient);
}
@Test
public void shouldBehaveACertainWay() {
//customize mock, call component methods, assert results...
}
}
package com.example.myapp;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyApplication.class)
@WebAppConfiguration
@ActiveProfiles("test")
public class Component1TestWithRealCommunication {
@Autowired
Component1 component1; //<-- the thing we're testing. wants the real implementations in this test.
@Autowired
ServiceClient mockedServiceClient;
@Before
public void setup() {
reset(mockedServiceClient);
}
@Test
public void shouldBehaveACertainWay() {
//call component methods, assert results...
}
}
Le problème avec la configuration ci-dessus est que le composant d'analyse configuré dans MyApplication ramasse Component1TestWithFakeCommunication.ContextConfiguration, si je reçois une maquette ServiceClient même dans Component1TestWithRealCommunication où je veux le vrai ServiceClient mise en œuvre.
Bien que je pourrais utiliser @Autocâblés constructeurs et mettre en place les composants moi-même dans les deux tests, il ya une quantité suffisante de trucs avec des réglages compliqués que je préférerais avoir le Printemps TestContext mis en place pour moi (par exemple, Spring Data JPA dépôts, les composants de bibliothèques en dehors de l'application qui tirent les haricots du Printemps contexte, etc.). Imbrication d'un Printemps de configuration à l'intérieur de l'épreuve qui peut localement remplacer certaines bean définitions dans le Printemps contexte se sent comme il doit être propre façon de le faire; le seul inconvénient est que ces imbriquée configurations finissent par toucher tout le Printemps TestContext tests de la base de leur configuration sur MyApplication (le composant qui scanne le package de l'application).
Comment puis-je modifier mon installation, donc je suis toujours un "la plupart du temps réel" Printemps contexte pour mes tests avec seulement quelques localement remplacé les haricots dans chaque classe de test?
OriginalL'auteur Jonathan Fuerth | 2016-09-02
Vous devez vous connecter pour publier un commentaire.
Les points suivants devraient vous aider à atteindre votre objectif en introduisant un nouveau
fake-communication
profil qui est le seul applicable à l'essai de courant de classe.C'est une solution de travail, mais en quelque sorte-de "travail-autour-de-ish" et aussi un peu gênant. Printemps de démarrage fournit une meilleure façon avec son exclusion automatique du filtre. Un exemple attaché à une réponse différente.
Merci!!!! Vous avez résolu mon promlem
OriginalL'auteur Sam Brannen
Si vous avez un
@SpringBootTest
vous pouvez simplement annoter le service que vous voulez pour se moquer avec@MockBean
. Aussi simple que cela.OriginalL'auteur Jorge Viana
Je voudrais faire une ou deux choses:
@ComponentScan
ing.Component1TestWithFakeCommunication
, changement@SpringApplicationConfiguration(classes = MyApplication.class)
à@SpringApplicationConfiguration(classes = {MyApplication.class, Component1TestWithFakeCommunication.ContextConfiguration.class})
Qui devrait donner du Printemps des informations suffisantes pour se moquer de l'essai de haricots, mais il doit empêcher l'exécution
ApplicationContext
de remarquer votre test de haricots.OriginalL'auteur Josh Ghiloni
Vous pouvez utiliser d'autres explicite profils pour éviter de telles configurations de test pour être ramassé (comme suggéré dans une autre réponse). J'ai fait aussi, et même créé une bibliothèque d'appui.
Cependant, Spring-Boot est intelligent et il possède une fonction de type "filtre" pour résoudre ce problème automatiquement. Pour que cela fonctionne, vous devez retirer votre
@ComponentScan
annotation, ce qui permettrait de trouver vos configurations de test, et de laisser le@SpringBootApplication
faire le travail. Dans votre exemple, il suffit de retirer ce:et de le remplacer par:
Vous pouvez aussi avoir besoin d'annoter votre test comme
@SpringBootTest
. Cela devrait éviter d'auto-numériser n'importe quel intérieur de la classe des configurations (composants) à l'exception de ceux résidant dans la actuel test.OriginalL'auteur Marwin