2012-04-27 3 views
1

Je suis en train de déplacer toutes mes configurations Spring vers le code Java. J'ai rencontré un problème où je veux maintenant définir quel profil j'utilise basé sur un commutateur de ligne de commande ou un profil maven, etc ... Je veux aussi éviter d'avoir à placer toutes les mêmes annotations sur chacun de mes tests Des classes. Ce n'est pas une application web, mais plutôt une suite de tests fonctionnels.Java Spring ApplicationContext Configuration

Voici ma tentative:

public class CompanyApplicationContextInitializer 
    implements ApplicationContextInitializer<ConfigurableApplicationContext> { 

    @Override 
    public void initialize(final ConfigurableApplicationContext applicationContext) { 
    final AnnotationConfigApplicationContext rootContext = new AnnotationConfigApplicationContext(); 
    rootContext.getEnvironment().setActiveProfiles(System.getProperty("spring.profile.active", "local")); 
    rootContext.register(LocalConfiguration.class, SauceLabsConfiguration.class); 
    } 
} 

J'ai mes essais annotés avec les éléments suivants:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = CompanyApplicationContextInitializer.class) 

Cependant, lorsque je tente d'exécuter mes tests, mes pièces autowired ne sont pas situés. Suis-je sur la bonne voie? Comment puis-je câbler dans cette classe pour définir par programme mon ApplicationContext?

Répondre

5

Le problème avec votre exemple ci-dessus est que vous passez une classe ApplicationContextInitializer @ ContextConfiguration classes #. L'attribut #classes est destiné à accepter les classes marquées avec l'annotation @Configuration de Spring. ApplicationContextInitializer est principalement destiné aux applications Web, où il est difficile d'obtenir un accès par programme à WebApplicationContext. Le paramètre "contextInitializerClasses" init-param peut être passé à Spring DispatcherServlet, et Spring appelle votre implémentation ACI au bon moment, ce qui vous permet de manipuler le contexte de l'application avant #refresh().

Dans votre cas, il semble que vous vous intéressez uniquement à l'activation de profils pour un test d'intégration. Donc votre ACI est inutile. Marquez votre test d'intégration avec l'annotation @ActiveProfiles de Spring pour déterminer les profils actifs.

Notez que si spring.profiles.active a été défini en tant que propriété système JVM ou variable d'environnement, le ou les profils spécifiés seront activés automatiquement. c'est-à-dire qu'il n'est pas nécessaire d'appeler System # getProperty comme vous le faites dans votre implémentation ACI. Une chose à noter, cependant, est que selon la logique de votre implémentation ACI, il semble que vous souhaitiez revenir à un profil nommé "local" si spring.profiles.active est fourni sous la forme d'une propriété système ou d'une variable d'environnement. Vous serez peut-être intéressé de savoir qu'il existe un "profil par défaut réservé" nommé littéralement "par défaut". Cela a probablement la même sémantique que vous recherchez avec votre profil "local". Envisagez de renommer votre profil "local" par défaut.

Enfin, notez qu'il existe une demande d'amélioration ouverte pour fournir le support ApplicationContextInitializer dans les classes @ContextConfiguration: https://jira.springsource.org/browse/SPR-9011. Vous pourriez vouloir mettre une montre sur cela. Cela vous permettrait, par exemple, une option simple pour activer localement 'local' si aucun autre profil n'est actif.

+0

J'espérais éviter d'avoir une classe de test de base qui définirait toutes les options de configuration, mais il semblerait que je n'aurai pas le choix (actuellement). J'espérais éviter d'avoir à placer quel profil était actif sur chacune des classes de test (ce qui est facilement fait ici avec la propriété JVM), mais j'espérais vraiment éviter d'avoir à placer l'annotation ContextConfiguration sur chacune de mes classes de test, donc le déplacer vers un test de niveau de base permettra d'atténuer ce problème. – Scott

+0

L'annotation @ActiveProfiles peut être utilisée dans une classe de base et s'appliquerait à toutes les sous-classes. En outre, cette annotation possède un certain nombre de propriétés, dont une appelée inheritLocations. Voir le Javadoc. –

1

Essayez d'ajouter les emplacements de votre XML contexte de l'application à la deuxième annotation:

@ContextConfiguration(locations = { 
    "classpath:applicationContext.xml" 
}) 
+0

J'essaierai quand je l'aurai lundi, mais il n'y a pas de fichier xml actuellement. Est-ce que j'ajoute un juste todeclare ce haricot? Semble contre-intuitif en utilisant toute la configuration de Java ailleurs. – Scott

+0

Non, modifiez l'annotation pour que le contexte de votre application soit chargé au démarrage. – duffymo

Questions connexes