Au cours de ma carrière passée, j'ai souvent constaté que certaines personnes n'ont pas écrit de code de test, et la raison pour laquelle ils prétendaient écrire était qu'ils ne pouvaient pas facilement écrire des cas de test couvrant plusieurs modules différents. Eh bien, je crois que la plupart d'entre eux manquent de moyens techniques plus faciles à maîtriser ou n'ont pas le temps de le comprendre. Après tout, il y aura toujours diverses pressions telles que les progrès au travail. Parce que je ne sais pas comment tester, j'ignore souvent les tests d'intégration, et les problèmes causés deviennent des logiciels pires, de plus en plus de bogues et de clients plus déçus. Je veux donc partager des expériences personnelles pour dévoiler le mystère des tests d'intégration.
Comment mieux intégrer les tests des projets basés sur le printemps <Br /> Utilisation des outils: printemps, Junit, Mockito
Imaginez qu'il existe un tel projet de printemps qui intègre certains services externes, tels que certains services Web bancaires. Ensuite, les problèmes rencontrés lors de la rédaction de cas de test pour ce projet et de la réalisation de ces tests dans un système d'intégration continue sont fondamentalement les mêmes:
1. Il y aura des transactions dans chaque test, et chaque transaction nécessite un coût monétaire, qui sera finalement supporté par le client;
2. Les demandes excessives émises lors des tests peuvent être considérées comme des demandes malveillantes, ce qui peut entraîner le blocage du compte de la banque, avec la conséquence de l'échec du test;
3. Lorsque les tests sont effectués à l'aide d'un environnement de non-production, les résultats des tests ne sont pas très fiables. De même, la conséquence est que le test échoue.
Habituellement, lorsque vous testez une seule classe, le problème est facile à résoudre car vous pouvez virtualiser certains services externes pour l'appel. Mais lors du test de l'ensemble du processus métier énorme, cela signifie que vous devez tester plusieurs composants, et pour le moment, vous devez incorporer ces composants dans le conteneur à ressort pour la gestion. Heureusement, Spring comprend un très excellent cadre de test qui vous permet d'injecter des haricots à partir de fichiers de configuration de l'environnement de production dans l'environnement de test, mais pour ceux appelés services externes, nous devons écrire nous-mêmes des implémentations simulées. La première réaction des gens ordinaires peut être de réinjecter (modifier) les haricots injectés par le ressort pendant le stade d'installation du test, mais cette méthode doit être soigneusement considérée.
AVERTISSEMENT: De cette façon, votre code de test rompt le propre comportement du conteneur, il n'y a donc aucune garantie que ce sera le même que les résultats de votre test dans un environnement réel.
En fait, au lieu d'implémenter d'abord la classe Mock, puis de le réinjecter dans le haricot requis, nous pouvons laisser le printemps nous aider à injecter la classe simulée depuis le début. Voyons-le avec le code.
L'exemple de projet contient une classe appelée BankService, représentant l'appel au service externe, et une classe appelée UserBalanceService, qui appelle BankService. UserBalancesService est implémenté très simple, juste pour terminer la conversion de l'équilibre de la chaîne en double type.
Code source de BankService.java:
Interface publique BankService {String getBalanceByEmail (Email String);} Code source de BankServiceImpl.java:
classe publique BankServiceIMPl implémente BankService {@Override public String getBalanceByEmail (String Email) {Throw New UnsupportedOperationException ("L'opération a échoué en raison d'une exception externe"); }} Code source de userBalancesservice.java:
Interface userBalancesservice {double getAccountBalance (courriel de chaîne);} Code source de userBalancesserviceImpl.java:
classe publique UserBalanceserServiceImpl implémente UserBalingService {@autowired private BankService BankService; @Override public double getAccountBalance (chaîne e-mail) {return double.valueof (bankService.getBalanceByEmail (e-mail)); }} Ensuite, il y a le fichier de configuration XML de Spring, ajoutant la déclaration de bean requise.
Code source d'ApplicationContext.xml:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" XSI: ScheMalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id = "BankService" /> <Bean Id = "userbalancesservice" /> </ beans "
Voici le code source de la classe de test userBalancesserviceImplTest.java:
@Runwith (springjunit4classrunner.class) @contextConfiguration (locations = "classpath: /springtest/springockito/applicationcontext.xml") Classe publique UserBalancesserviceIMPLProfileTest {@Autowired Private UserBaliancesservice UserBalancesservice; @Autowired Private BankService BankService; @Test public void houstreTurnMockEdBalance () {double balance = userBalancesservice.getAccountBalance ("[email protected]"); assertequals (bilan, double.valueof (123.45d)); }} Comme nous nous y attendions, la méthode de test rapporte une exception non soutenue d'Exception. Notre objectif actuel est de remplacer BankService par notre implémentation de simulation. Il est normal d'utiliser Mockito directement pour générer des haricots d'usine, mais il y a une meilleure option, utilisez le framework Springockito. Vous pouvez avoir une idée difficile avant de continuer.
La question restante est simple: comment injecter le ressort dans un bean simulé au lieu d'un vrai bean, il n'y avait pas d'autre moyen avant le printemps 3.1 sauf pour créer un nouveau fichier de configuration XML. Mais depuis que Spring a introduit la définition de profil des haricots, nous avons une solution plus élégante, bien que cette approche nécessite également un fichier de configuration XML supplémentaire spécifiquement pour les tests. Voici le code du fichier de configuration TestApplicationContext.xml utilisé pour tester:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: mockito = "http://www.mockito.org/spring/mockito" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/bans/www.spring http://www.mockito.org/spring/mockito https://bitbucket.org/kubek2k/springockito/raw/tip/springockito/src/main/resources/spring/mockito.xsd "> <importation ressource = "classpath: /springtest/springockito/applicationContext.xml" /> <beans profil = "Springtest"> <mockito: mock id = "BankService" /> </bans> </ beans>
Le code source de la classe de test userBalancesserviceImplProfileTest.java après avoir apporté des modifications correspondantes:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (locations = "classpath: /springtest/springockito/testApplicationContext.xml") @ activeProfiles (Profils = {"Springtest"}) public Class userBalancesserviceServiceService; @Autowired Private BankService BankService; @Before public void setup () lève une exception {mockito.when (BankService.getBalanceByEmail ("[email protected]")). ThereTrurn (string.valueof (123.45d)); } @Test public void ommérmockockedBalance () {double bilan = userBalancesservice.getAccountBalance ("[email protected]"); assertequals (bilan, double.valueof (123.45d)); }} Vous avez peut-être remarqué que dans la méthode de configuration, nous définissons le comportement simulé et ajoutons l'annotation @profile à la classe. Cette annotation active un profil appelé SpringTest, de sorte que le bean simulé à l'aide de Springockito peut être automatiquement injecté partout où il en a besoin. Le résultat d'exécution de ce test sera réussi car Spring injecte la version simulée par Springockito, et non la version déclarée dans ApplicationContext.xml.
Continuez à optimiser nos tests
Si nous pouvons apporter davantage la solution à ce problème, cet article ne semble pas être défectueux. Springockito propose un autre nom appelé
Springockito Annotation Framework, qui nous permet d'utiliser des annotations dans les classes de test pour injecter des classes simulées. Avant de continuer à lire, il est préférable d'aller sur le site Web pour jeter un œil. Ok, voici le code de test modifié.
Code source de userBalancesserviceImpLannotationTest.java: @runwith (springjunit4classrunner.class) @contextConfiguration (Loader = SpringockitoConTextLoder UserBalancesservice userBalancesservice; @Autowired @replacewithMock BankService privé BankService; @Before public void setup () lève une exception {mockito.when (bankService.getBalanceByEmail ("[email protected]")). ThereTurturn (string.valueof (ValueOf (123.45d))); } @Test public void ommérmockockedBalance () {double bilan = userBalancesservice.getAccountBalance ("[email protected]"); asserTequals (solde, valeurof (123.45d)); }} Veuillez noter qu'il n'y a pas de fichier de configuration XML nouvellement introduit ici, mais l'applicationcontext.xml de l'environnement formel est directement utilisé. Nous utilisons l'annotation @replacewithmock pour marquer le bean de type banc de type, puis définissons le comportement de la classe Mock dans la méthode de configuration.
post-scriptum
Le projet Springockito-Annotations a un énorme avantage, c'est-à-dire qu'il construit notre code de test sur la couverture de dépendance, afin que nous n'ayons pas besoin de définir des fichiers de configuration XML supplémentaires ou de modifier les fichiers de configuration de l'environnement de production pour les tests. Si Springockito-Annotations n'est pas utilisée, nous n'avons pas d'autre choix que de définir des fichiers de configuration XML supplémentaires. Par conséquent, je recommande fortement d'utiliser Springockito-Annotations dans vos tests d'intégration afin que vous puissiez minimiser l'impact de vos cas de test sur votre code de production et supprimer également la charge de maintenir des fichiers de configuration XML supplémentaires.
Post-scriptum
La rédaction de tests d'intégration pour les projets de printemps est vraiment beaucoup plus facile. Le code de l'article fait référence à mon propre github.
Lien de traduction: http://www.codeceo.com/article/spring-test-is-easy.html
Anglais original: testez-moi si vous pouvez # 1 (Spring Framework)
Traducteur: Sandbox Wang, réseau de codage
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.