different types matchers provided mockito
comment inverser un tableau java
Une introduction aux différents types de matchers dans Mockito.
Moques et espions à Mockito ont été expliqués en détail dans notre précédent tutoriel de Série de formation Mockito .
Que sont les Matchers?
Les matchers sont comme des expressions régulières ou des jokers où au lieu d'une entrée spécifique (et / ou d'une sortie), vous spécifiez une plage / un type d'entrée / sortie en fonction des stubs / espions qui peuvent être restés et des appels aux stubs peuvent être vérifiés.
Tous les matchers Mockito font partie de ‘ Mockito » classe statique.
Les matchers sont un outil puissant, qui permet une manière abrégée de configurer les stubs ainsi que de vérifier les invocations sur les stubs en mentionnant les entrées d'argument comme des types génériques à des valeurs spécifiques en fonction du cas d'utilisation ou du scénario.
Ce que vous apprendrez:
Types de Matchers à Mockito
Il existe en gros 2 types de matchers à Mockito ou en termes d'utilisation, les matchers peuvent être utilisés pour les 2 catégories ci-dessous:
- Correspondants d'arguments lors de la configuration du stub
- Verification Matchers pour vérifier les appels réels aux stubs
Pour les deux types de Matchers, c'est-à-dire Argument et Vérification, Mockito fournit un vaste ensemble de Matchers (Cliquez ici pour obtenir une liste complète des correspondants).
Correspondants d'arguments
Voici les plus utilisés:
Pour tout ce qui suit, envisageons de tester une IntegerList:
final List mockedIntList = mock(ArrayList.class);
#1) any () - Accepte n'importe quel objet (y compris null).
when (mockedIntList.get( any ())).thenReturn(3);
#deux) any (classe de langage Java) -
Exemple : any (ClassUnderTest.class) - Ceci est une variante plus spécifique de any () et n'acceptera que les objets du type de classe mentionné comme paramètre de modèle.
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
# 3) anyBoolean (), anyByte (), anyInt (), anyString (), anyDouble (), anyFloat (), anyList () et bien d'autres - Tous acceptent tout objet du type de données correspondant ainsi que les valeurs nulles.
when (mockedIntList.get( any Int())).thenReturn(3);
# 4) Arguments spécifiques - Dans les cas où les arguments réels sont connus à l'avance, il est toujours recommandé de les utiliser car ils fournissent plus de confiance par rapport aux types d'arguments génériques.
Exemple:
when(mockedIntList.get(1)).thenReturn(3);
Correspondants de vérification
Il existe des correspondants spécialisés qui sont disponibles pour attendre / affirmer des choses comme non. d'invocations sur le simulacre.
Pour tous les correspondances ci-dessous, considérons la même liste d'exemples que celle que nous avons utilisée auparavant.
final List mockedIntList = mock(ArrayList.class);
# 1) Invocations simulées
(je) L'appel simple sur Mock vérifie si la méthode simulée a été appelée / interagie ou non en définissant la taille de la liste simulée sur 5.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList).size();
(ii) Un nombre spécifique d'interactions avec une méthode simulée vérifie le nombre de non. des fois, le simulacre devait être appelé.
Questions d'entretien de développeur sql pour 2-3 ans d'expérience
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(1)).size();
Afin de vérifier 0 interactions, changez simplement la valeur de 1 à 0 comme argument pour le matcher times ().
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(0)).size();
En cas d'échec, il renvoie les exceptions suivantes:
à) Lorsque les appels attendus sont inférieurs aux appels réels:
Exemple: Recherché 2 fois, mais invoqué 3 fois, puis Mockito revient - ' verification.TooManyActualInvocations '
Exemple de code:
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(2)).get(anyInt());
b) Lorsque les appels attendus sont plus que les appels réels:
Exemple: Recherché 2 fois, mais invoqué 1 fois, puis Mockito revient - ' verification.TooLittleActualInvocations '
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(4)).get(anyInt());
(iii) Aucune interaction avec la méthode spécifique de l'objet simulé.
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); // Assert verify(mockedIntList, never()).size();
(iv) Vérifiez l'ordre des interactions simulées - Ceci est particulièrement utile lorsque vous souhaitez vérifier l'ordre dans lequel les méthodes sur les objets simulés ont été appelées.
Exemple: Base de données comme des opérations où un test doit vérifier l'ordre dans lequel les mises à jour de la base de données ont eu lieu.
Pour illustrer cela par l'exemple - Continuons avec la même liste d’exemples.
Supposons maintenant que l'ordre des appels aux méthodes de liste soit dans l'ordre, c'est-à-dire get (5), size (), get (2). Ainsi, l'ordre de vérification devrait également être le même.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size(); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt());
En cas de mauvaise séquence de vérification, une exception est levée par Mockito - c'est-à-dire ' verification.VerificationInOrderFailure ».
Ainsi, dans l'exemple ci-dessus, si je change l'ordre de vérification en interchangeant les 2 dernières lignes, je commencerai à recevoir l'exception VerificationInOrderFailure.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size();
(v) Vérifiez que l'interaction s'est produite au moins / au plus grand nombre de fois.
(à) au moins:
Exemple: atleast (3) - Vérifie que l'objet simulé a été invoqué / interagi avec au moins trois fois pendant le test. Ainsi, l'une des interactions 3 ou supérieures à 3 devrait permettre la réussite de la vérification.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atLeast(2)).get(anyInt());
En cas d'erreurs, c'est-à-dire lorsque les invocations réelles ne correspondent pas, la même exception est lancée comme avec le matcher times (), c'est-à-dire ' verification.TooLittleActualInvocations »
(b) au plus:
Exemple: atmost (3) - vérifie si l'objet simulé a été invoqué / interagi avec au moins trois fois pendant le test. Ainsi, n'importe laquelle des interactions 0,1,2 ou 3 avec le simulacre devrait faire de la vérification une réussite.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atMost(2)).get(anyInt()); verify(mockedIntList, atMost(2)).size();
# 2) Correspondance d'arguments
Dans l'invocation ci-dessus, les correspondants peuvent être combinés avec les correspondants d'argument pour valider les arguments avec lesquels le simulacre a été appelé.
- tout()
- Valeurs spécifiques - Vérifiez avec les valeurs spécifiques lorsque les arguments sont connus à l'avance.
- D'autres correspondants d'argument comme - anyInt (), anyString () etc.
Conseils & Astuces
# 1) Utilisation de la capture d'argument pendant la vérification
La vérification de capture d'argument est généralement utile lorsque l'argument utilisé par une méthode stubbed n'est pas passé directement via un appel de méthode, mais est créé en interne lorsque la méthode testée est appelée.
Ceci est essentiellement utile lorsque votre méthode dépend d'un ou plusieurs collaborateurs dont le comportement a été stubé. Les arguments passés à ces collaborateurs sont un objet interne ou un ensemble d'arguments entièrement nouveau.
La validation de l'argument réel avec lequel les collaborateurs auraient été appelés assure une grande confiance dans le code qui est testé.
Mockito fournit ArgumentCaptor qui peut être utilisé avec vérification, puis lorsque «AgumentCaptor.getValue ()» est appelé, nous pouvons affirmer l'argument capturé réel par rapport à celui attendu.
Pour illustrer cela, reportez-vous à l'exemple ci-dessous:
Dans la méthode ci-dessous, CalculatePrice est le modèle dont la classe InventoryModel est créée à l'intérieur du corps de la méthode qui est ensuite utilisée par InventoryService pour la mise à jour.
Maintenant, si vous souhaitez écrire un test pour valider avec quel argument le service inventaire a été appelé, vous pouvez simplement utiliser l'objet ArgumentCaptor de type classe InventoryModel.
Méthode sous test:
public double calculatePrice(int itemSkuCode) { double price = 0; // get Item details ItemSku sku = itemService.getItemDetails(itemSkuCode); // update item inventory InventoryModel model = new InventoryModel(); model.setItemSku(sku); model.setItemSuppliers(new String(){'Supplier1'}); inventoryService.updateInventory(model, 1); return sku.getPrice(); }
Code de test: Regardez l'étape de vérification où InventoryService est vérifié, l'objet argumentCaptor est substitué pour lequel l'argument doit être mis en correspondance.
Ensuite, affirmez simplement la valeur en appelant la méthode getValue () sur l'objet ArgumentCaptor.
Exemple: ArgumentCaptorObject.getValue ()
public void calculatePrice_withValidItemSku_returnsSuccess() { // Arrange ItemSku item1 = new ItemSku(); item1.setApplicableDiscount(5.00); item1.setPrice(100.00); CustomerProfile customerProfile = new CustomerProfile(); customerProfile.setExtraLoyaltyDiscountPercentage(2.00); double expectedPrice = 93.00; // Arrange when(mockedItemService.getItemDetails(anyInt())).thenReturn(item1); ArgumentCaptor argCaptorInventoryModel = ArgumentCaptor.forClass(InventoryModel.class); // Act priceCalculator.calculatePrice(1234); // Assert verify(mockedItemService).getItemDetails(anyInt()); verify(mockedInventoryService).updateInventory(argCaptorInventoryModel.capture(), eq(1)); assertEquals(argCaptorInventoryModel.getValue().itemSku, item1);
Sans ArgumentCaptor, il n'y aurait aucun moyen d'identifier avec quel argument l'appel de service a été effectué. Le mieux est d'utiliser «any ()» ou «any (InventoryModel.class)» pour vérifier les arguments.
# 2) Exceptions / Erreurs courantes lors de l'utilisation de Matchers
Lors de l'utilisation de Matchers, certaines conventions doivent être suivies qui, si elles ne sont pas suivies, entraînent la levée d'une exception. Le plus courant que je suis tombé sur est en stubbing et en vérifiant.
Si vous utilisez un argumentMatchers et si la méthode stubbed a plus d'un argument (s), alors soit tous les arguments doivent être mentionnés avec des matchers, sinon aucun d'eux ne doit avoir de matchers. Maintenant, qu'est-ce que cela signifie?
Essayons de comprendre cela avec un scénario (puis un exemple de code pour ce scénario)
- Supposons que la méthode testée ait une signature comme -
concatenateString (chaîne arg1, chaîne arg2) - Maintenant, lors du stubbing - supposons que vous connaissiez la valeur de arg1, mais arg2 est inconnue, vous décidez donc d'utiliser un argument matcher comme - any () ou anyString () et en spécifiant une valeur pour le premier argument comme un texte «bonjour».
- Lorsque l'étape ci-dessus est implémentée et que le test est exécuté, le test lève une exception appelée «InvalidUseOfMatchersException»
Essayons de comprendre cela avec un exemple:
Code de test:
// Arrange when(a gMatcher.concatenateString('hello', anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
Classe sous test:
public class ArgMatcher { public String concatenateString(String arg1, String arg2) { return arg1.concat(arg2); } }
Lorsque le test ci-dessus est exécuté, il retourne dans ' InvalidUseOfMatchersException '
Maintenant, quelle est la raison de cette exception?
lecteur de fichiers swf aucun objet flash Shockwave installé
C'est le stubbing utilisant des matchers de partie et une chaîne fixe de partie. Il existe maintenant 2 façons de se débarrasser de ces types d'exceptions (veuillez également noter que ce comportement s'applique à la fois aux configurations Mock et au comportement).
# 1) Utilisez Argument Matchers pour tous les arguments:
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
# 2) Utilisez eq () comme Argument Matcher où l'argument est connu. Donc, au lieu de spécifier l'argument comme 'bonjour', spécifiez-le comme 'eq (' bonjour ') et cela devrait permettre de réussir le stubbing.
// Arrange when(argMatcher.concatenateString(anyString(), eq('world'))).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'world'); // Assert verify(argMatcher).concatenateString(anyString(), eq('world'));
Conclusion
Dans cet article, nous avons vu comment utiliser différents types de matchers fournis par Mockito.
Ici, nous avons couvert les plus utilisés. Pour consulter la liste complète, la documentation de la bibliothèque Mockito est une bonne source de référence.
Consultez notre prochain tutoriel pour en savoir plus sur les méthodes de moquerie privées, statiques et nulles.
Tutoriel PREV | Tutoriel SUIVANT
lecture recommandée
- Créer des simulacres et des espions dans Mockito avec des exemples de code
- Tutoriel Mockito: Framework Mockito pour la simulation dans les tests unitaires
- Types de risques dans les projets logiciels
- Types de données Python
- Types de données C ++
- Top 12 des questions d'entrevue Mockito (entretien Mocking Framework)
- Se moquer des méthodes privées, statiques et nulles à l'aide de Mockito
- Types d'héritage en C ++