web-dev-qa-db-fra.com

Comment dire au printemps de ne charger que les beans nécessaires au test JUnit?

Une question simple qui pourrait avoir une réponse avancée.

La question: Ma question est, existe-t-il un moyen d'instancier uniquement les classes, dans votre contexte d'application, nécessaires pour ce test JUnit spécifique?

La raison: mon contexte d'application devient assez grand. Je fais aussi beaucoup de tests d'intégration, donc je suppose que vous comprendrez quand je dis que chaque fois que je lance un test, toutes les classes de mon contexte d'application sont instanciées et cela prend du temps.

L'exemple:

Dire classe Foo injecter uniquement la barre

public class Foo {

@Inject
Bar bar;

@Test
public void testrunSomeMethod() throws RegisterFault {
    bar.runSomeMethod();
}

mais le contexte d'application a des beans foobar et bar. Je sais que ce n'est pas un contexte d'application vaild, mais soyez assuré que tout mon code fonctionne.

<beans>
     <bean id="foobar" class="some.package.FooBar"/>
     <bean id="bar" class="some.package.Bar"/>
<beans>

Alors, comment puis-je dire à Spring d'instancier uniquement Bar et d'ignorer FooBar pour la classe de test foo.

Je vous remercie.

19
SandMan

Ce n'est pas une réponse directe, donc je ne voudrais pas marquer comme solution. Mais j'espère que c'est utile.

En général, je vois trois options.

  1. Comme VinayVeluri a répondu gentiment. Créez des contextes séparés et lancez-les séparément dans chaque test.

  2. Créez un contexte une fois pour tous les tests. Tout comme ici: Réutiliser le contexte de l'application Spring dans les classes de test junit C'est une grande optimisation pour tester tous les tests à la fois.

  3. Mélangez ces deux premiers points. Créez un contexte plus petit uniquement à des fins de test. Se moquer de ce qui n'est jamais testé mais peut lancer NPE etc. Comme ici: Injection de mockito dans un bean Spring pour booster la construction du contexte. Et réutilisez-le comme au point 2. Génération unique pour tous les tests. Personnellement, j'irais avec celui-là.

  4. Celui-ci attend la réponse sur une sorte de lanceur de test intelligent, qui crée le contexte minimum requis par test.

3
Sarseth

Pensez à ajouter default-lazy-init="true" à votre balise xml beans contextuelle de printemps (ou ajoutez lazy-init="true" aux beans spécifiques dont le démarrage est long). Cela garantira que seuls les beans sont créés qui sont appelés avec applicationContext.getBean (class-or-bean-name) ou injectés via @Autowired/@Inject dans vos tests. (Certains autres types de haricots comme @Scheduled des beans seront néanmoins créés mais vous devez vérifier si c'est un problème ou non)

(si vous utilisez spring Java, ajoutez @Lazy aux fichiers de configuration)

Mise en garde - S'il existe un bean qui n'est pas initialisé explicitement avec applicationContext.getBean () ou injecté comme une dépendance utilisée par le bean obtenu en utilisant applicationContext.getBean (), alors ce bean NE SERA PLUS construit ou initialisé. En fonction de votre application, cela peut entraîner l'échec de certaines choses OR non. Vous pouvez peut-être marquer sélectivement ces beans comme lazy-init="false"

7
Deepak

Oui, nous pouvons le faire, en utilisant le contexte par cas de test. Préparez un fichier xml de contexte de test avec les beans requis pour votre scénario de test.

Si vous utilisez maven, placez le test-context.xml sous le dossier src/test/resources.

Annotez votre classe de test requise avec l'annotation suivante

@ContextConfiguration(locations = "classpath:test-application-context.xml")

Cela permet de charger uniquement des beans spécifiques pour le scénario de test.

Si vous avez deux types de cas de test, alors

@Runwith(SpringJUnit4Runner.class)
@ContextConfiguration(locations = "classpath:test-context-case1.xml")
public class TestClassCase1 {}

@Runwith(SpringJUnit4Runner.class)
@ContextConfiguration(locations = "classpath:test-context-case2.xml")
public class TestClassCase2 {}
3
VinayVeluri