mocking private static
Lær Mocking Private, Static og Void metoder i Mockito med eksempler:
I denne serien hands-on Opplæringsprogrammer om Mockito , vi så på forskjellige typer Mockito Matchers i den siste opplæringen.
Generelt sett håner private og statiske metoder under kategorien uvanlig hån.
Hvis behovet oppstår for å spotte private og statiske metoder / klasser, indikerer det dårlig omformet kode og er egentlig ikke en testbar kode og er mest sannsynlig at noen eldre koder som ikke ble brukt til å være veldig enhetstestvennlige.
Når det er sagt, eksisterer det fortsatt støtte for Mocking private og statiske metoder av få enhetstestingsrammer som PowerMockito (og ikke direkte av Mockito).
Spottende 'ugyldige' metoder er vanlige, da det kan være metoder som i det vesentlige ikke returnerer noe, som å oppdatere en databaserad (betrakt det som en PUT-operasjon av et Rest API-endepunkt som aksepterer en inngang og ikke returnerer noen utdata).
Mockito gir full støtte for mocking ugyldige metoder, som vi vil se med eksempler i denne artikkelen.
beste DVD-kopieringsprogramvare for mac
Hva du vil lære:
- Powermock - En kort introduksjon
- Hånende private metoder
- Hånlige statiske metoder
- Mocking Void Methods
- Tips og triks
- Konklusjon
- Anbefalt lesing
Powermock - En kort introduksjon
For Mockito er det ingen direkte støtte for å spotte private og statiske metoder. For å teste private metoder, må du refaktor koden for å endre tilgangen til beskyttet (eller pakke), og du må unngå statiske / endelige metoder.
Mockito, etter min mening, gir ikke bevisst støtte for denne typen mocks, siden bruk av slike kodekonstruksjoner er kodelukt og dårlig utformet kode.
Men det er rammer som støtter spott for private og statiske metoder.
Powermock utvider kapasiteten til andre rammer som EasyMock og Mockito og gir muligheten til å spotte statiske og private metoder.
# 1) Hvordan: Powermock gjør dette ved hjelp av tilpasset bytecode-manipulering for å støtte mocking private og statiske metoder, avsluttende klasser, konstruktører og så videre.
# 2) Støttede pakker: Powermock tilbyr to utvidelses-APIer - en for Mockito og en for easyMock. Av hensyn til denne artikkelen skal vi skrive eksempler med Mockito-utvidelsen for power mock.
# 3) Syntaks :Powermockito har en nesten lignende syntaks som Mockito, bortsett fra noen tilleggsmetoder for å spotte statiske og private metoder.
# 4) Oppsett av Powermockito
For å inkludere Mockito-biblioteket i gradebaserte prosjekter, nedenfor er bibliotekene som skal inkluderes:
testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '1.7.4' testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.4'
Lignende avhengigheter er også tilgjengelige for maven.
Powermock-api-mockito2 - Biblioteket må inneholde Mockito-utvidelser for Powermockito.
Powermock-module-junit4 - Modulen kreves for å inkludere PowerMockRunner (som er en tilpasset løper som skal brukes til å kjøre tester med PowerMockito).
Et viktig poeng å merke seg her er at PowerMock ikke støtter Junit5 testløper. Derfor må testene skrives mot Junit4, og testene må utføres med PowerMockRunner.
For å bruke PowerMockRunner - testklassen må merkes med @RunWith (PowerMockRunner.class)
La oss nå diskutere, spotte private, statiske og ugyldige metoder i detalj!
Hånende private metoder
Å spotte private metoder, som kalles internt fra en metode som testes, kan være uunngåelig på bestemte tidspunkter. Ved hjelp av powermockito er dette mulig, og verifiseringen gjøres ved hjelp av en ny metode som heter 'verifisere privat'
La oss ta enEksempel der metoden under test kaller en privat metode (som returnerer en boolsk). For å stubbe denne metoden for å returnere true / false, avhengig av testen, må en stub settes opp på denne klassen.
For dette eksemplet opprettes klassen under test som en spioninstans med spott på få grensesnittanrop og privat metodeinnkallelse.
Viktige punkter til Mock Private Method:
#1) Testmetoden eller testklassen må kommenteres med @ PrepareForTest (ClassUnderTest). Denne kommentaren ber powerMockito om å forberede visse klasser for testing.
Dette vil for det meste være de klassene som må være Bytecode manipulert . Vanligvis for avsluttende klasser, klasser som inneholder private og / eller statiske metoder som kreves spottet under testing.
Eksempel:
@PrepareForTest(PriceCalculator.class)
#to) Å sette stub på en privat metode.
Syntaks - når (hån eller spioninstans, 'privateMethodName'). thenReturn (// returverdi)
Eksempel:
when (priceCalculatorSpy, 'isCustomerAnonymous').thenReturn(false);
# 3) For å bekrefte den stubbede private metoden.
Syntaks - verifiserePrivate (mockedInstance) .invoke (“privateMethodName”)
Eksempel:
verifyPrivate (priceCalculator).invoke('isCustomerAnonymous');
Fullstendig testprøve: Fortsetter det samme eksemplet fra forrige artikler, hvor priceCalculator har noen hånede avhengigheter som itemService, userService etc.
Vi har opprettet en ny metode kalt - calcnepricewithprivateMethod, som kaller en privat metode i samme klasse og returnerer om kunden er anonym eller ikke.
@Test @PrepareForTest(PriceCalculator.class) public void calculatePriceForAnonymous_witStubbedPrivateMethod_returnsCorrectPrice() throws Exception { // Arrange ItemSku item1 = new ItemSku(); item1.setApplicableDiscount(5.00); item1.setPrice(100.00); double expectedPrice = 90.00; // Setting up stubbed responses using mocks when(priceCalculatorSpy, 'isCustomerAnonymous').thenReturn(false); when(mockedItemService.getItemDetails(123)).thenReturn(item1); // Act double actualDiscountedPrice = priceCalculatorSpy.calculatePriceWithPrivateMethod(123); // Assert verifyPrivate(priceCalculator).invoke('isCustomerAnonymous'); assertEquals(expectedPrice, actualDiscountedPrice); }
Hånlige statiske metoder
Statiske metoder kan hånes på en lignende måte som vi så for de private metodene.
Når en metode som testes, innebærer å bruke en statisk metode fra samme klasse (eller fra en annen klasse), må vi ta den klassen med i PreparForTest-merknaden før testen (eller i testklassen).
Viktige punkter til Mock Static Methods:
#1) Testmetoden eller testklassen må kommenteres med @ PrepareForTest (ClassUnderTest). I likhet med å spotte private metoder / klasser, er dette også nødvendig for statiske klasser.
#to) Et ekstra trinn som kreves for statiske metoder er - mockStatic (// navn på statisk klasse)
Eksempel:
mockStatic(DiscountCategoryFinder.class)
# 3) Å sette opp stub på en statisk metode, er like bra som å stubbe en hvilken som helst metode på andre grensesnitt / klasse mock-forekomster.
For eksempel: For å stubbe getDiscountCategory () (som returnerer en enum DiscountCategory med verdier PREMIUM & GENERELT) statisk metode i DiscountCategoryFinder-klassen, bare stub som følger:
when (DiscountCategoryFinder. getDiscountCategory ()).thenReturn(DiscountCategory. PREMIUM );
# 4) For å bekrefte mock-oppsettet på den endelige / statiske metoden, kan verifiser statisk () -metoden brukes.
Eksempel:
verifyStatic (DiscountCategoryFinder.class, times (1));
Mocking Void Methods
La oss først prøve å forstå hva slags brukssaker som kan innebære stubbing av ugyldige metoder:
#1) Metodesamtaler for eksempel - som sender en e-postvarsling under prosessen.
For eksempel :Anta at du endrer passordet ditt for bankkontoen din, når endringen er vellykket, mottar du et varsel via e-posten din.
Dette kan betraktes som / changePassword som et POST-anrop til Bank API som inkluderer et ugyldig metodeanrop for å sende et e-postvarsel til kunden.
#to) Et annet vanlig eksempel på anropet om ugyldig metode er oppdaterte forespørsler til en DB som tar litt innspill og ikke returnerer noe.
Stubbing ugyldige metoder (dvs. metodene som ikke returnerer noe, eller ellers kaster et unntak), kan håndteres ved hjelp av funksjonene doNothing (), doThrow () og doAnswer (), doCallRealMethod () . Det krever at stubben settes opp ved hjelp av metodene ovenfor i henhold til testforventningene.
Vær også oppmerksom på at alle anrop for ugyldige metoder som standard spottes til doNothing (). Derfor, selv om et eksplisitt mock-oppsett ikke gjøres på TOMROM metoden anrop, er standard oppførsel fortsatt å gjøre ingenting ().
La oss se eksempler på alle disse funksjonene:
La oss anta at det er en klasse for alle eksemplene StudentScoreUpdates som har en metode calcularSumAndStore (). Denne metoden beregner summen av poeng (som input) og kaller a tomrom metode updateScores () på databaseImplementation-forekomst.
public class StudentScoreUpdates { public IDatabase databaseImpl; public StudentScoreUpdates(IDatabase databaseImpl) { this.databaseImpl = databaseImpl; } public void calculateSumAndStore(String studentId, int() scores) { int total = 0; for(int score : scores) { total = total + score; } // write total to DB databaseImpl.updateScores(studentId, total); } }
Vi skriver enhetstester for mock-metoden med eksemplene nedenfor:
# 1) gjør ingenting () - doNothing () er standard oppførsel for ugyldige metodeanrop i Mockito, dvs. selv om du bekrefter en samtale om ugyldig metode (uten å eksplisitt sette opp et tomrom til å gjøre ingenting (), vil verifiseringen fortsatt være vellykket)
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb() { // Arrange studentScores = new StudentScoreUpdates(mockDatabase); int() scores = {60,70,90}; Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); // Act studentScores.calculateSumAndStore('student1', scores); // Assert Mockito.verify(mockDatabase, Mockito.times(1)).updateScores(anyString(), anyInt()); }
Andre bruksområder sammen med doNothing ()
til) Når ugyldighetsmetoden kalles flere ganger, og du vil konfigurere forskjellige svar for forskjellige påkallelser, som - doNothing () for første påkallelse og kaste et unntak for neste påkallelse.
For eksempel :Sett opp mock slik:
qa ingeniørintervju spørsmål og svar
Mockito. doNothing ().doThrow(new RuntimeException()).when(mockDatabase).updateScores( anyString (), anyInt ());
b) Når du vil fange argumentene som ugyldighetsmetoden ble kalt til, bør ArgumentCaptor-funksjonaliteten i Mockito brukes. Dette gir en ekstra bekreftelse av argumenter som metoden ble kalt med.
Eksempel med ArgumentCaptor:
public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb() { // Arrange studentScores = new StudentScoreUpdates(mockDatabase); int() scores = {60,70,90}; Mockito.doNothing().when(mockDatabase).updateScores(anyString(), anyInt()); ArgumentCaptor studentIdArgument = ArgumentCaptor.forClass(String.class); // Act studentScores.calculateSumAndStore('Student1', scores); // Assert Mockito.verify(mockDatabase, Mockito.times(1)).updateScores(studentIdArgument.capture(), anyInt()); assertEquals('Student1', studentIdArgument.getValue()); }
# 2) doTrow ()- Dette er nyttig når du bare vil kaste et unntak når ugyldighetsmetoden påkalles fra metoden som testes.
For eksempel:
Mockito.doThrow(newRuntimeException()).when(mockDatabase).updateScores ( anyString (), anyInt ());
# 3) doAnswer ()- doAnswer () gir ganske enkelt et grensesnitt for å gjøre litt tilpasset logikk.
F.eks. Endring av noen verdi gjennom de overførte argumentene, retur av egendefinerte verdier / data som en normal stub ikke kunne ha returnert spesielt for ugyldige metoder.
For demonstrasjonsformål - jeg har stubbet metoden updateScores () ugyldig for å returnere en “ svar() ”Og skriv ut verdien av ett av argumentene som skulle ha blitt gitt når metoden skulle ha blitt kalt.
Kodeeksempel:
@Test public void calculateSumAndStore_withValidInput_shouldCalculateAndUpdateResultInDb() { // Arrange studentScores = new StudentScoreUpdates(mockDatabaseImpl); int() scores = {60,70,90}; Mockito.doCallRealMethod().when(mockDatabaseImpl).updateScores(anyString(), anyInt()); doAnswer(invocation -> { Object() args = invocation.getArguments(); Object mock = invocation.getMock(); System.out.println(args(0)); return mock; }).when(mockDatabaseImpl).updateScores(anyString(), anyInt()); // Act studentScores.calculateSumAndStore('Student1', scores); // Assert Mockito.verify(mockDatabaseImpl, Mockito.times(1)).updateScores(anyString(), anyInt()); }
# 4) doCallRealMethod ()- Delvise mocks ligner stubber (hvor du kan kalle virkelige metoder for noen av metodene og stubbe ut resten).
For ugyldige metoder gir mockito en spesiell funksjon kalt doCallRealMethod () som kan brukes når du prøver å sette opp mocken. Hva dette vil gjøre, er å kalle den virkelige ugyldighetsmetoden med de faktiske argumentene.
For eksempel:
Mockito. doCallRealMethod ().when(mockDatabaseImpl).updateScores( anyString (), anyInt ());
Tips og triks
# 1) Inkludert flere statiske klasser i samme testmetode / klasse- Bruke PowerMockito hvis det er behov for å spotte flere statiske endelige klasser, så blir klassene i @ PrepareForTest kommentar kan nevnes som kommaadskilt verdi som en matrise (den aksepterer i hovedsak en matrise med klassenavnene).
Eksempel:
@PrepareForTest({PriceCalculator.class, DiscountCategoryFinder.class})
Som vist i eksemplet ovenfor, antar at både PriceCalculator og DiscountCategoryFinder er siste klasser som må spottes. Begge disse kan nevnes som en rekke klasser i PrepareForTest-kommentar og kan stubbes i testmetoden.
# 2) PrepareForTest-attributtposisjonering - Plasseringen av dette attributtet er viktig med hensyn til typen tester som inngår i testklassen.
Hvis alle testene må bruke samme sluttklasse, er det fornuftig å nevne dette attributtet på testklassenivå, som ganske enkelt betyr at den forberedte klassen vil være tilgjengelig for alle testmetodene. I motsetning til dette, hvis merknaden er nevnt på testmetoden, vil den bare være tilgjengelig for de spesifikke testene
Konklusjon
I denne opplæringen diskuterte vi ulike tilnærminger for å spotte statiske, endelige og ugyldige metoder.
Selv om bruk av mange statiske eller endelige metoder hindrer testbarhet, og fremdeles, er det støtte tilgjengelig for testing / mocking for å hjelpe til med å lage enhetstester for å oppnå større tillit til koden / applikasjonen selv for eldre kode som vanligvis ikke er vant til være utformet for testbarhet.
For statiske og endelige metoder har Mockito ikke støtte utenom boksen, men biblioteker som PowerMockito (som tungt arver mange ting fra Mockito) gir slik støtte og må faktisk utføre manipulering av kodekoder for å støtte disse funksjonene.
Mockito out of the box støtter stubbing ugyldige metoder og gir forskjellige metoder som doNothing, doAnswer, doThrow, doCallRealMethod etc. og kan brukes i henhold til testens krav.
De ofte stilte spørsmålene om Mockito-intervju er beskrevet i vår neste opplæring.
PREV Opplæring | NESTE veiledning
Anbefalt lesing
- Mockito Tutorial: Mockito Framework for Mocking in Unit Testing
- Topp 12 spørsmål om Mockito-intervju (Mocking Framework Interview)
- Statisk i C ++
- Java-tråder med metoder og livssyklus
- Opprette Mocks and Spies i Mockito med kodeeksempler
- Ulike typer matchere levert av Mockito
- Metoder og teknikker for forebygging av feil
- Hvordan bruke metoder i SoapUI for utføring av bulkprøver - SoapUI opplæring # 10