different types matchers provided mockito
forskjellen mellom funksjonell og ikke-funksjonell testing
En introduksjon til forskjellige typer matchere i Mockito.
Mocks and Spies in Mockito ble forklart i detalj i vår forrige opplæring av detaljert Mockito treningsserie .
Hva er Matchers?
Matchere er som regex eller jokertegn der du i stedet for en bestemt inngang (og eller utgang) spesifiserer et område / type inngang / utgang basert på hvilke stubber / spioner som kan hvile og samtaler til stubber kan bekreftes.
Alle Mockito-matcherne er en del av Mockito ’ statisk klasse.
Matchere er et kraftig verktøy som muliggjør en kortfattet måte å sette opp stubber på, samt å verifisere påkallinger på stubbene ved å nevne argumentinnganger som generiske typer til spesifikke verdier, avhengig av brukstilfelle eller scenario.
Hva du vil lære:
Typer Matchers i Mockito
Det er stort sett to typer matchere i Mockito eller når det gjelder bruk, kan matchere brukes i kategoriene nedenfor:
- Argument Matchers under Stub-oppsett
- Verifikasjonsmatchere for å verifisere faktiske samtaler til stubber
For begge typer Matchers, dvs. Argument og Verification, gir Mockito et stort sett matchers (Click her for å få en komplett liste over matcherne).
Argument Matchers
Nedenfor er de mest brukte:
For alt det nedenfor, la oss vurdere å teste en IntegerList:
final List mockedIntList = mock(ArrayList.class);
#1) any () - Godtar ethvert objekt (inkludert null).
when (mockedIntList.get( any ())).thenReturn(3);
#to) hvilken som helst (java språkkurs) -
Eksempel : any (ClassUnderTest.class) - Dette er en mer spesifikk variant av hvilken som helst () og godtar bare objekter av klassetypen som er nevnt som malparameter.
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
# 3) anyBoolean (), anyByte (), anyInt (), anyString (), anyDouble (), anyFloat (), anyList () og mange flere - Alle disse aksepterer ethvert objekt av den tilsvarende datatypen samt nullverdier.
when (mockedIntList.get( any Int())).thenReturn(3);
# 4) Spesifikke argumenter - I tilfeller der faktiske argumenter er kjent på forhånd, anbefales det alltid å bruke dem ettersom de gir mer tillit i forhold til generiske argumenttyper.
Eksempel:
when(mockedIntList.get(1)).thenReturn(3);
Verifikasjonsmatchere
Det er noen spesialiserte matchere som er tilgjengelige for å forvente / hevde ting som nei. av påkallelser på mock.
For alle nedenstående matchere, la oss se på den samme listen over eksempler som vi har brukt før.
final List mockedIntList = mock(ArrayList.class);
# 1) Mock Invocations
(Jeg) Enkel påkallelse på Mock verifiserer om den spottede metoden ble kalt / samhandlet eller ikke ved å sette størrelsen på den spottede listen til 5.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList).size();
(ii) Spesifikk antall interaksjoner med en hånet metode verifiserer antall nei. av ganger ble spottet forventet å bli kalt.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(1)).size();
For å verifisere for 0 interaksjoner, endrer du bare verdien fra 1 til 0 som argument for times () matcher.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(0)).size();
Ved feil returnerer den følgende unntak:
til) Når de forventede påkallelsene er mindre enn de faktiske påkallelsene:
Eksempel: Ønsket 2 ganger, men påkalt tre ganger, så returnerer Mockito - “ verification.TooManyActualInvocations '
Eksempel kode:
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 forventede påkallelsene er mer enn de faktiske påkallelsene:
Eksempel: Ønsket 2 ganger, men påkalt 1 gang, så returnerer 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) Ingen interaksjoner med den spesifikke metoden for det spottede 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) Bekreft rekkefølgen på spottede interaksjoner - Dette er spesielt nyttig når du vil sikre rekkefølgen som metodene på de spottede objektene ble kalt til.
Eksempel: Database som operasjoner der en test skal verifisere rekkefølgen databaseoppdateringene skjedde i.
For å illustrere dette ved eksempel - La oss fortsette med den samme listen over eksempler.
La oss anta at rekkefølgen på anrop til listen over metoder var i rekkefølge, dvs. få (5), størrelse (), få (2). Så rekkefølgen på bekreftelsen skal også være den samme.
// 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 tilfelle feil bekreftelsessekvens, kastes et unntak av Mockito - dvs. verification.VerificationInOrderFailure ”.
Så i eksemplet ovenfor, hvis jeg endrer rekkefølgen på bekreftelse ved å bytte de to siste linjene, begynner jeg å få unntak fra 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) Bekreft at interaksjonen har skjedd minst / flest ganger.
(til) i det minste:
Eksempel: minst (3) - Bekrefter at den spottede gjenstanden ble påkalt / samhandlet med minst tre ganger under testen. Så noen av interaksjonene 3 eller større enn 3 bør gjøre verifiseringen vellykket.
// 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 tilfelle feil, dvs. når de faktiske påkallelsene ikke stemmer overens, kastes det samme unntaket som med times () matcher, dvs. verification.TooLittleActualInvocations ”
hva er en .apk fil
(b) på det meste:
Eksempel: atmost (3) - verifiserer om det spottede objektet ble påkalt / samhandlet med det meste tre ganger under testen. Så noen av 0,1,2 eller 3 interaksjoner med mocken bør gjøre verifiseringen vellykket.
// 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) Argumentmatching
I ovennevnte påkalling kan matchere kombineres med argumentmatcherne for å validere argumentene som mock ble kalt med.
- noen()
- Spesifikke verdier - Bekreft med de spesifikke verdiene når argumentene er kjent på forhånd.
- Andre argumentmatchere som - anyInt (), anyString () etc.
Tips og triks
# 1) Bruk av Argument Capture under verifisering
Verifisering av argumentfangst er vanligvis nyttig når argumentet som brukes av en eller annen stubmet metode, ikke sendes direkte via en metodeanrop, men opprettes internt når metoden under test kalles.
Dette er i det vesentlige nyttig der metoden din avhenger av en eller flere samarbeidspartnere hvis atferd har blitt stubbet. Argumentene som sendes til disse samarbeidspartnerne er et internt objekt eller et helt nytt argument.
Validering av det faktiske argumentet som samarbeidspartnerne ville blitt kalt med, sikrer mye tillit til koden som testes.
Mockito tilbyr ArgumentCaptor som kan brukes med verifisering, og når “AgumentCaptor.getValue ()” blir kalt, kan vi hevde det faktiske fangede argumentet mot det forventede.
For å illustrere dette, se eksemplet nedenfor:
I metoden nedenfor er calcprice modellen med klassen InventoryModel er opprettet inne i metodekroppen som deretter brukes av InventoryService for oppdatering.
Nå hvis du vil skrive en test for å validere hvilket argument inventarService ble kalt til, kan du ganske enkelt bruke ArgumentCaptor-objektet av typen InventoryModel-klasse.
hvordan du spiller en shockwave flash-fil
Metode 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(); }
Testkode: Se på verifiseringstrinnet der inventarService er verifisert, argumentCaptor-objektet erstattes av hvilket argument som må matches.
Påstå deretter verdien ved å påkalle getValue () -metoden på ArgumentCaptor-objektet.
Eksempel: 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);
Uten ArgumentCaptor ville det ikke være noen måte å identifisere hvilket argument tjenesteanropet ble gjort med. Best mulig er å bruke 'any ()' eller 'any (InventoryModel.class)' for å bekrefte argumenter.
# 2) Vanlige unntak / feil når du bruker Matchers
Mens du bruker Matchers, er det visse konvensjoner som bør følges, som hvis ikke følges, resulterer i at et unntak blir kastet. Den vanligste som jeg kom over er mens du stubber og verifiserer.
Hvis du bruker noen argumentMatchers, og hvis den stubbed-metoden har mer enn ett argument (er), bør enten alle argumentene nevnes med matchere, ellers skal ingen av dem ha matchere. Nå, hva betyr dette?
La oss prøve å forstå dette med et scenario (og deretter kodeeksempel for dette scenariet)
- Anta at metoden som testes har en signatur som -
concatenateString (String arg1, String arg2) - Nå når du stubber - antar at du vet verdien av arg1, men arg2 er ukjent, så du bestemmer deg for å bruke en argumentmatcher som - any () eller anyString () og spesifisere en verdi for det første argumentet som en tekst 'hallo'.
- Når trinnet ovenfor er implementert og testen utføres, kaster testen et unntak kalt 'InvalidUseOfMatchersException'
La oss prøve å forstå dette med et eksempel:
Testkode:
// Arrange when(a gMatcher.concatenateString('hello', anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
Klasse under test:
public class ArgMatcher { public String concatenateString(String arg1, String arg2) { return arg1.concat(arg2); } }
Når testen ovenfor er utført, returnerer den i “ InvalidUseOfMatchersException '
Nå, hva er grunnen til dette unntaket?
Det er stubbingen ved hjelp av delmatchere og delvis fast streng, dvs. vi har nevnt en argumentmatcher som 'hei' og andre som anyString (). Nå er det to måter å bli kvitt slike unntak (Vær også oppmerksom på at denne oppførselen gjelder både Mock-oppsett og atferd).
# 1) Bruk Argument Matchers for alle argumentene:
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
# 2) Bruk eq () som Argument Matcher der argumentet er kjent. Så i stedet for å spesifisere argumentet som “hei”, spesifiser det som “eq (“ hei ”), og dette skal gjøre stubbingen vellykket.
// Arrange when(argMatcher.concatenateString(anyString(), eq('world'))).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'world'); // Assert verify(argMatcher).concatenateString(anyString(), eq('world'));
Konklusjon
I denne artikkelen så vi hvordan du bruker forskjellige typer matchere levert av Mockito.
Her dekket vi de mest brukte. For å referere til den komplette listen er Mockito Library-dokumentasjon en god referanse.
Ta en titt på den kommende veiledningen for å lære mer om private, statiske og ugyldige metoder for spott.
PREV Opplæring | NESTE veiledning
Anbefalt lesing
- Opprette Mocks and Spies i Mockito med kodeeksempler
- Mockito Tutorial: Mockito Framework for Mocking in Unit Testing
- Typer av risikoer i programvareprosjekter
- Python datatyper
- C ++ datatyper
- Topp 12 Mockito intervju spørsmål (Mocking Framework Interview)
- Spotte private, statiske og ugyldige metoder ved bruk av Mockito
- Typer arv i C ++