Préface
Cet article présente comment utiliser Springboot + Junit + Mockito pour les tests unitaires et sélectionnez une classe qui correspond aux transactions pour effectuer des tests unitaires.
Comprendre les exigences avant les tests unitaires
Pour écrire un bon test unique, vous devez d'abord comprendre les exigences. Ce n'est qu'en sachant quoi faire que vous savez comment tester. Mais cet article parle principalement de l'utilisation de Mockito, et il n'est pas nécessaire de prêter attention à des besoins spécifiques. Par conséquent, cette section omet la description des exigences spécifiques.
Isoler les dépendances externes
Cas 1. Comment contrôler la valeur de retour de l'objet de dépendance annoté par @Autowired ou @Resource Annotation dans la classe testée
Prendre le match (MatchingOrder BuyOrder, MatchingOrder Sellorder) de la méthode sous Test MatchingServiceImpl.Java comme exemple
Tested Class MatchingServiceImpl
classe publique MatchingServiceIMPl implémente MatchingService {private static final logger log = loggerfactory.getLogger (correspondingServiceImpl.class); @Autowired Private Quoseservice Quoseservice; ... Public MatchingResult Matching (MatchingOrder BuyOrder, MatchingOrder SellOrder) {int CurrentPrice = QuteService.getCurrentPriceByProduct (BuyOrder.GetProductCode ()); MatchingResult Result = new MatchingResult (); if (sellorder! = null && acheterOrder! = null && sellorder.getprice () <= buyorder.getprice ()) {...}}QuoService.getCurrentPriceByProduct (BuyOrder.getProductCode ()); Afin d'accéder à Redis pour obtenir le devis actuel, nous devons se moquer du devis de dépendance externe pour contrôler la valeur de retour de la méthode GetCurrentPriceByProduct. Vous pouvez le faire en utilisant Mockito, comme suit:
Test Class MatchingServiceImplTest
Classe publique MatchServiceIMPLTest étend MockitobedTest {/ ** * Les objets marqués par @Mock seront automatiquement injectés dans l'objet marqué par @ injectmocks * / @mock Private Quoseservice Quoseservice; / ** * <pre> * Objets à tester, marqués avec @InjectMocks, ces objets marqués par @mock seront automatiquement injectés. * Un autre point à noter est que le match de MatchingServiceImpl est directement nouveau (il est OK s'il n'est pas nouveau après Mockito 1.9), plutôt que d'injecté dans le conteneur à ressort. Parce que ici, je n'ai pas besoin d'obtenir d'autres dépendances du conteneur de ressort *, et je n'ai pas besoin de base de données, redis, zookeeper, mq, et rien en dépend, donc j'ai directement nouveau * </pre> * / @InjectMocks private MatcherServiceImplArService = new MatchServiceIMPL (); @Test public void testmatching_successwhencurrentPricebetweenBuypriceAndellprice () {MatchingOrder BuyOrder = new MatchingOrder (); BuyOrder.SetPrice (1000); BuyOrder.SetCount (23); MatchingOrder SellOrder = new MatchingOrder (); sellorder.setPrice (800); sellorder.setCount (20); // Méthode Stubbing (Méthode Stubbing) // Lorsque (x) .TheRenturn (Y): Renvoie la valeur spécifiée lorsque la méthode spécifiée est appelée mockito.when (QuteService.getCurrentPriceByProduct (mockito.anystring ())). Thereturn (900); MatchingResult Result = MatchingService.matching (BuyOrder, sellorder); org.junit.assersert.assertequals (true, result.issuccess ()); // affirme si le matchmaking est réussi org.junit.assert.assertequals (20, result.gettratecout ()); // affirme la quantité de transaction org.junit.essert.assertequals (900, résultat.GetTrAdEprEPRICE ()); // affirme si le dernier devis répond aux attentes}Cas 2. Lorsque la fonction A est testée, comment contrôler la valeur de retour de la fonction B dans la classe testée?
Par exemple, il existe une fonction startBuyprocess dans MatchingServiceImpl, qui appelle d'autres fonctions de la classe, telles que GetTopsellOrder et correspondant. Comment contrôler les valeurs de retour de ces deux fonctions?
Le problème à résoudre ici est de savoir comment exécuter réellement la méthode mesurée (telle que startBuyprocess) d'une classe "Partial Mock" testée de classe, tandis que d'autres méthodes (telles que GetTopsellOrder) sont empilées (pas vraiment entrées et exécutées).
Tested Class MatchingServiceImpl
Protected void startBuyprocess (MatchOrder BuyOrder, booléen waitFormatching) {while (true) {// Le meilleur prix de la contrepartie MatchingOrder topSellOrder = getTopsellOrder (buyOrder.getProductCode ()); MatchingResult MatchingResult = Matching (BuyOrder, topSellOrder); if (correspondingResult.isccess ()) {domatchingSuccess (buyOrder, topSellOrder, correspondingResult, correspondingType.buy); if (buyOrder.getCount () <= 0) {Break; }} else {if (waitFormatching) {// ajouter pour correspondre à la file d'attente à additionner addToMatchingBuy (buyOrder); } else {// révoquez l'ordre SendCanclemsg (BuyOrder); } casser; }}}}L'utilisation de mockito.spy () peut réaliser une "simulation partielle"
Test Class MatchingServiceImplTest.TestStartBuyProcess_InCaseOfMatchingSuccess
/ ** * * Testez si le traitement de la méthode de startBuyprocess après réussite du matchmaking répond aux attentes, c'est-à-dire tester le comportement après être entré dans la succursale de jugement suivante * {@Link MatchServiceIMP MatchingType.Buy); * * if (BuyOrder.getCount () <= 0) {* Break; *} *} * </ pre> * * / @Test public void testStartBuyProcess_InCaseOfMatchingSuccress () {MatchingOrder BuyOrder = new MatchingOrder (); BuyOrder.SetPrice (700); BuyOrder.SetCount (23); // Utilisez mockito.spy () pour orienter partiellement le MatchingService MatchingService = mockito.spy (MatchingService); MatchingResult FirstMatchingResult = new MatchingResult (); FirstMatchingResult.SetSuccess (true); FirstMatchingResult.SetTradeCount (20); MatchingResult SecondMatchingResult = new MatchingResult (); SecondMatchingResult.SetSuccess (false); // doreturn (x) .When (obj) .Method () Après avoir empilé les méthodes, après avoir empilé les méthodes, le programme renvoie la valeur spécifiée comme prévu lors de l'exécution de ces méthodes. Les méthodes qui ne sont pas empilées seront exécutées seront exécutées en temps réel. // Deux doreturns signifie que FirstMatchingResult est renvoyé lorsque MatchingService. .matching (mockito.any (MatchingOrder.class), mockito.any (MatchingOrder.class)); MatchingOrder SellOrder = new MatchingOrder (); sellorder.setPrice (600); sellorder.setCount (20); // Empile la méthode GetTopsellOrder mockito.doreTurn (sellorder) .When (MatchingService) .getTopsellOrder (mockito.anystring ()); // empilant la méthode externe qui dépend de Jedis mockito.when (jedisclient.incrby (mockito.anystring (), mockito.anylong ())). ThereTurturn (0l); // startBuyprocess est la fonction testée. Si vous ne tassez pas, MatchingService.StartBuyprocess (BuyOrder, True); // L'affirmation suivante de la somme de contrôle est de tester le comportement de la méthode DomatchingSuccess, qui est également le but de ce test.// Vérification peut être utilisée pour vérifier combien de fois une certaine méthode de classe a été exécutée? Voici pour vérifier si Jedisclient.zremFirst a été exécuté une fois mockito.verify (Jedisclient, mockito.times (1)). ZremFirst (mockito.anystring ()); org.junit.assert.AsserTequals (3, buyOrder.getCount ()); org.junit.assert.AsserTequals (0, sellOrder.getCount ()); } L'utilisation de l'espion a été démontrée. Parlons de la «granularité» des tests unitaires de TestStartBuyprocess_incaseofMatchingSuccess.
Le but de TestStartBuyprocess_InCaseOfMatchingSuccess est de tester DomatchingSuccess. Nous avons travaillé très dur pour terminer les préparations précédentes avant de pouvoir tester DomatchingSuccess.
Une meilleure pratique devrait être de démarrer une nouvelle méthode de test pour tester DomatchingSuccess séparément, et l'accent est également concentré. Après que DomatchingSuccess a été écrasé, StartBuyprocess peut simplement couvrir sa propre succursale de jugement. La couverture est toujours obtenue et le code de test est plus facile à entretenir. TestStartBuyprocess_InCaseofMatchingSuccess est facilement affecté par les changements dus à trop de responsabilités considérées. De petites choses changent peut affecter sa fonction normale.
Présentation du cadre de test Maven dépendances
<dependency> <proupId> JUnit </rom grouped> <Artifactid> JUnit </ artifactId> <De version> 4.11 </ version> <ccope> Test </cope> </ Dependency> <Dedency> <ProupId> org.mockito </proped> <Artifactid> Mockito-all </Rifactid> <version> 1.10.19 </ version> <ccope> Test </ccope> </ Dependency> <Dedency> <ProupId> org.SpringFramework </prolsid> <Artefactive> Spring-Test </ Artifactid> <DERNENCE> 4.2.5.Release </DERNE> <POPE> Test </cope> </Dependency>
Contexte Construction de Springboot + Junit + Mockito
MockitobedTest
@Runwith (springjunit4classrunner.class) @springApplicationConfiguration (Classes = TestApplication.Class) Public Abstract Class MockitobasedTest {@Before Public Void Settup () lève des annotations de cas de test de la classe de tests. }} // D'autres classes de test héritent de MockitobedTest 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.