different types matchers provided mockito
var kan jag hitta min nätverkssäkerhetsnyckel
En introduktion till olika typer av matchare i Mockito.
Hånar och spioner i Mockito förklarades i detalj i vår tidigare handledning av detaljerad Mockito träningsserie .
Vad är Matchers?
Matchare är som regex eller jokertecken där du istället för en specifik ingång (och eller utgång) anger ett intervall / typ av input / output baserat på vilka stubbar / spioner som kan vila och samtal till stubbar kan verifieras.
Alla Mockito-matchare är en del av Mockito ' statisk klass.
Matchare är ett kraftfullt verktyg som möjliggör ett kortfattat sätt att ställa in stubbar samt verifiera anrop på stubbarna genom att nämna argumentinmatningar som generiska typer till specifika värden beroende på användningsfall eller scenario.
Vad du kommer att lära dig:
Typer av Matchers i Mockito
Det finns i stort sett två typer av matchare i Mockito eller när det gäller användning kan matchare användas för nedanstående 2 kategorier:
- Argument Matchers under Stub-installationen
- Verifieringsmatchare för att verifiera faktiska samtal till stubbar
För båda typerna av Matchers, dvs Argument och Verification, tillhandahåller Mockito en enorm uppsättning matchers (Click här för att få en komplett lista över matcharna).
Argument Matchers
Nedan listas de mest använda:
För allt nedan, överväga att testa en IntegerList:
final List mockedIntList = mock(ArrayList.class);
# 1) any () - Accepterar alla objekt (inklusive null).
when (mockedIntList.get( any ())).thenReturn(3);
#två) valfri (java språkklass) -
Exempel : any (ClassUnderTest.class) - Detta är en mer specifik variant av vilken som helst () och accepterar endast objekt av klasstypen som nämns som mallparameter.
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
# 3) anyBoolean (), anyByte (), anyInt (), anyString (), anyDouble (), anyFloat (), anyList () och många fler - Alla dessa accepterar alla objekt av motsvarande datatyp samt nullvärden.
when (mockedIntList.get( any Int())).thenReturn(3);
# 4) Specifika argument - I fall där faktiska argument är kända i förväg rekommenderas det alltid att använda dem eftersom de ger mer självförtroende jämfört med generiska argumenttyper.
Exempel:
when(mockedIntList.get(1)).thenReturn(3);
Verifieringsmatchare
Det finns några specialiserade matchare som finns att förvänta / hävda saker som nej. av anrop på mocken.
För alla nedanstående matchare, låt oss överväga samma lista med exempel som vi har använt tidigare.
final List mockedIntList = mock(ArrayList.class);
# 1) Mock Invocations
(i) Enkel anrop på Mock verifierar om den hånade metoden anropades / interagerades eller inte genom att ställa in storleken på den hånade listan till 5.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList).size();
(ii) Specifikt antal interaktioner med en hånad metod verifierar antalet nr. av gånger förväntades håna att kallas.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(1)).size();
För att verifiera för 0 interaktioner, ändra bara värdet från 1 till 0 som argument för matchningstider ().
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(0)).size();
I händelse av fel returnerar följande undantag:
till) När de förväntade anropen är mindre än de faktiska anropen:
Exempel: Ville 2 gånger, men åberopade tre gånger, sedan återvänder Mockito - “ verification.TooManyActualInvocations '
Exempelkod:
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) När de förväntade anropen är mer än de faktiska anropen:
Exempel: Ville ha två gånger, men åberopade en gång, sedan återvänder Mockito - “ 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) Inga interaktioner med den specifika metoden för det spottade objektet.
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) Verifiera ordningen på hånade interaktioner - Detta är särskilt användbart när du vill säkerställa den ordning i vilken metoderna på de hånade objekten anropades.
Exempel: Databasliknande operationer där ett test ska verifiera i vilken ordning databasuppdateringarna hände.
För att illustrera detta med exempel - Låt oss fortsätta med samma lista som exempel.
Låt oss nu anta att ordningen på samtal till listmetoder var i följd, dvs get (5), size (), get (2). Så, ordningen för verifiering bör också vara densamma.
// 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());
I händelse av fel verifieringssekvens kastas ett undantag av Mockito - dvs. verification.VerificationInOrderFailure ”.
Så i exemplet ovan, om jag ändrar ordningen för verifiering genom att byta ut de två sista raderna, kommer jag att få undantag från 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) Verifiera att interaktionen har inträffat minst / minst antal gånger.
(till) åtminstone:
Exempel: minst (3) - Verifierar att det hånade objektet åberopades / interagerades med minst tre gånger under testet. Så någon av interaktionerna 3 eller större än 3 bör göra verifieringen framgångsrik.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atLeast(2)).get(anyInt());
I händelse av fel, dvs. när de faktiska anropen inte matchar, kastas samma undantag som med matcharen times (), dvs. verification.TooLittleActualInvocations ”
(b) som mest:
Exempel: atmost (3) - verifierar om det hånade objektet har åberopats / interagerat med högst tre gånger under testet. Så någon av 0,1,2 eller 3 interaktioner med mocken bör göra verifieringen framgångsrik.
// 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) Argumentmatchning
slå samman sortering i c ++
I ovanstående anrop kan matchare kombineras med argumentmatcharna för att validera argumenten som mock kallades till.
- några()
- Specifika värden - Verifiera med specifika värden när argumenten är kända i förväg.
- Andra argumentmatchare som - anyInt (), anyString () etc.
tips och tricks
# 1) Använda Argument Capture under verifiering
Verifiering av argumentupptagning är vanligtvis användbart om argumentet som används av någon stubbad metod inte skickas direkt via ett metodanrop utan skapas internt när metoden som testas anropas.
Detta är i huvudsak användbart när din metod beror på en eller flera medarbetare vars beteende har blivit avstängd. Argumenten som skickas till dessa medarbetare är ett internt objekt eller en helt ny argumentuppsättning.
Validering av det faktiska argumentet som samarbetspartnerna skulle ha kallats till garanterar mycket förtroende för koden som testas.
Mockito tillhandahåller ArgumentCaptor som kan användas för verifiering och sedan när “AgumentCaptor.getValue ()” anropas kan vi hävda det faktiska fångade argumentet mot det förväntade.
För att illustrera detta hänvisas till exemplet nedan:
I metoden nedan är calcprice modellen med klassen InventoryModel skapas inuti metodkroppen som sedan används av InventoryService för uppdatering.
Om du nu vill skriva ett test för att validera vilket argument inventariservice kallades till kan du helt enkelt använda ArgumentCaptor-objektet av typen InventoryModel-klass.
Metod under 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(); }
Testkod: Titta på verifieringssteget där inventoryService verifieras, argumentCaptor-objektet ersätts med vilket argument som måste matchas.
Ange bara värdet genom att anropa getValue () -metoden på ArgumentCaptor-objektet.
Exempel: 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);
Utan ArgumentCaptor skulle det inte finnas något sätt att identifiera vilket argument tjänsten kallades med. Bäst möjligt är att använda 'any ()' eller 'any (InventoryModel.class)' för att verifiera argument.
# 2) Vanliga undantag / fel när du använder Matchers
grep-kommando i unix shell-skript
När du använder Matchers finns det vissa konventioner som bör följas, vilket om de inte följs resulterar i att ett undantag kastas. Den vanligaste som jag stötte på är vid stubbning och verifiering.
Om du använder några argumentMatchers och om den stubbed-metoden har mer än ett eller flera argument, bör antingen alla argument nämnas med matchare, annars ska ingen av dem ha matchningar. Vad betyder detta nu?
Låt oss försöka förstå detta med ett scenario (och sedan kodexempel för detta scenario)
- Antag att metoden som testas har en signatur som -
concatenateString (String arg1, String arg2) - Nu när du stubbar - antar att du vet värdet på arg1, men arg2 är okänt, så du bestämmer dig för att använda en argumentmatchare som - any () eller anyString () och ange ett värde för det första argumentet som en text 'hej'.
- När steget ovan implementeras och testet utförs, ger testet ett undantag som kallas 'InvalidUseOfMatchersException'
Låt oss försöka förstå detta med ett exempel:
Testkod:
// Arrange when(a gMatcher.concatenateString('hello', anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
Klass under test:
public class ArgMatcher { public String concatenateString(String arg1, String arg2) { return arg1.concat(arg2); } }
När ovanstående test utförs återgår det i “ InvalidUseOfMatchersException '
Vad är anledningen till detta undantag nu?
Det är stubbningen med delmatchare och delvis fast sträng, dvs vi har nämnt en argumentmatcher som 'hej' och andra som anyString (). Nu finns det två sätt att bli av med denna typ av undantag (Observera också - att detta beteende gäller både Mock-inställningar och beteende).
# 1) Använd Argument Matchers för alla argument:
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
# 2) Använd eq () som Argument Matcher där argumentet är känt. Så istället för att ange argumentet som 'hej', ange det som 'ekv' ('hej') och detta skulle göra stubbningen framgångsrik.
// Arrange when(argMatcher.concatenateString(anyString(), eq('world'))).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'world'); // Assert verify(argMatcher).concatenateString(anyString(), eq('world'));
Slutsats
I den här artikeln såg vi hur man använder olika typer av matchare som tillhandahålls av Mockito.
Här täckte vi de mest använda. För att hänvisa till hela listan är Mockito Library-dokumentation en bra referenskälla.
Kolla in vår kommande handledning för att lära dig mer om privata, statiska och ogiltiga metoder för Mocking.
PREV-handledning | NÄSTA självstudie
Rekommenderad läsning
- Skapa Mocks and Spies i Mockito med kodexempel
- Mockito Tutorial: Mockito Framework for Mocking in Unit Testing
- Typer av risker i programvaruprojekt
- Python-datatyper
- C ++ datatyper
- Topp 12 Mockito-intervjufrågor (Mocking Framework Interview)
- Hånar privata, statiska och ogiltiga metoder med Mockito
- Typer av arv i C ++