mocking private static
Lær at spotte private, statiske og ugyldige metoder i Mockito med eksempler:
I denne række hands-on Tutorials om Mockito , vi kiggede på forskellige typer Mockito Matchers i den sidste tutorial.
Generelt håner private og statiske metoder under kategorien usædvanlig hån.
Hvis behovet opstår for at spotte private og statiske metoder / klasser, indikerer det dårligt ombygget kode og er ikke rigtig en testbar kode og er sandsynligvis en ældre kode, som ikke blev brugt til at være meget enhedstestvenlig.
Når det er sagt, eksisterer der stadig understøttelse af Mocking private og statiske metoder af få enhedstestrammer som PowerMockito (og ikke direkte af Mockito).
Spottende 'ugyldige' metoder er almindelige, da der kan være metoder, der i det væsentlige ikke returnerer noget, som f.eks. Opdatering af en databaserække (betragt det som en PUT-operation af et Rest API-slutpunkt, der accepterer et input og ikke returnerer noget output).
Mockito yder fuld support til mocking-ugyldige metoder, som vi vil se med eksempler i denne artikel.
hvordan man åbner mkv-fil på windows
Hvad du vil lære:
- Powermock - En kort introduktion
- Hånende private metoder
- Hånende statiske metoder
- Spottende ugyldige metoder
- Tips og tricks
- Konklusion
- Anbefalet læsning
Powermock - En kort introduktion
For Mockito er der ingen direkte støtte til at spotte private og statiske metoder. For at teste private metoder skal du refaktor koden for at ændre adgangen til beskyttet (eller pakke), og du bliver nødt til at undgå statiske / endelige metoder.
Mockito yder efter min mening bevidst ikke understøttelse af denne slags mocks, da brug af denne type kodekonstruktioner er kodelugt og dårligt designet kode.
Men der er rammer, der understøtter hån for private og statiske metoder.
Powermock udvider mulighederne i andre rammer som EasyMock og Mockito og giver mulighed for at spotte statiske og private metoder.
# 1) Hvordan: Powermock gør dette ved hjælp af brugerdefineret bytecode-manipulation for at støtte mocking af private og statiske metoder, afsluttende klasser, konstruktører og så videre.
# 2) Understøttede pakker: Powermock leverer 2 udvidelses-API'er - en til Mockito og en til easyMock. Af hensyn til denne artikel skal vi skrive eksempler med Mockito-udvidelsen til power mock.
# 3) Syntaks :Powermockito har en næsten lignende syntaks som Mockito, bortset fra nogle yderligere metoder til at spotte statiske og private metoder.
# 4) Opsætning af Powermockito
For at inkludere Mockito-biblioteket i gradbaserede projekter er nedenstående biblioteker, der skal medtages:
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 afhængigheder er også tilgængelige for maven.
Powermock-api-mockito2 - Biblioteket skal indeholde Mockito-udvidelser til Powermockito.
Powermock-modul-junit4 - Modul kræves for at inkludere PowerMockRunner (som er en brugerdefineret løber, der skal bruges til at køre tests med PowerMockito).
Et vigtigt punkt at bemærke her er, at PowerMock ikke understøtter Junit5 testløber. Derfor skal testene skrives mod Junit4, og testene skal udføres med PowerMockRunner.
For at bruge PowerMockRunner - testklassen skal kommenteres @RunWith (PowerMockRunner.class)
Lad os nu diskutere, spotte private, statiske og ugyldige metoder i detaljer!
Hånende private metoder
At spotte private metoder, der kaldes internt fra en testmetode, kan være uundgåelig på bestemte tidspunkter. Ved hjælp af powermockito er dette muligt, og verifikationen udføres ved hjælp af en ny metode med navnet 'verificere privat'
Lad os tage enEksempel hvor metoden under test kalder en privat metode (som returnerer en boolsk). For at stubbe denne metode til at returnere true / false afhængigt af testen, skal der oprettes en stub på denne klasse.
I dette eksempel oprettes klassen under test som en spioninstans med hån mod få interface-påkald og privat metodeopkald.
Vigtige punkter til Mock Private Method:
# 1) Testmetoden eller testklassen skal kommenteres med @ ForberedForTest (ClassUnderTest). Denne kommentar fortæller powerMockito at forberede visse klasser til test.
Disse vil for det meste være de klasser, der skal være Bytecode manipuleret . Typisk for afsluttende klasser, klasser indeholdende private og / eller statiske metoder, der skal bespottes under test.
Eksempel:
@PrepareForTest(PriceCalculator.class)
#to) For at indstille stub på en privat metode.
Syntaks - når (mock eller spion instans, 'privateMethodName'). thenReturn (// retur værdi)
Eksempel:
when (priceCalculatorSpy, 'isCustomerAnonymous').thenReturn(false);
# 3) For at bekræfte den stubede private metode.
Syntaks - verificerePrivat (mockedInstance) .invoke (“privateMethodName”)
Eksempel:
verifyPrivate (priceCalculator).invoke('isCustomerAnonymous');
Komplet testprøve: Fortsætter det samme eksempel fra de tidligere artikler, hvor priceCalculator har nogle hånede afhængigheder som itemService, userService osv.
Vi har oprettet en ny metode kaldet - calcpricewithprivateMethod, som kalder en privat metode inden for samme klasse og returnerer, uanset om kunden er anonym eller ej.
@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ånende statiske metoder
Statiske metoder kan hånes på en lignende måde, som vi så for de private metoder.
Når en metode, der testes, involverer brug af en statisk metode fra samme klasse (eller fra en anden klasse), bliver vi nødt til at medtage denne klasse i preparForTest-kommentaren før testen (eller i testklassen).
Vigtige punkter til Mock Static Methods:
# 1) Testmetoden eller testklassen skal kommenteres med @ ForberedForTest (ClassUnderTest). Svarende til at spotte private metoder / klasser, er dette også nødvendigt for statiske klasser.
#to) Et ekstra trin, der kræves til statiske metoder, er - mockStatic (// navn på statisk klasse)
Eksempel:
mockStatic(DiscountCategoryFinder.class)
# 3) At opsætte stub på en statisk metode er lige så godt som at stubbe enhver metode på andre interface / klasse mock-forekomster.
For eksempel: For at stub getDiscountCategory () (som returnerer en enum DiscountCategory med værdier PREMIUM & GENERELT) statisk metode i DiscountCategoryFinder klasse skal du blot stub som følger:
when (DiscountCategoryFinder. getDiscountCategory ()).thenReturn(DiscountCategory. PREMIUM );
# 4) For at verificere mock-opsætningen på den endelige / statiske metode kan metoden verificere statisk ().
Eksempel:
verifyStatic (DiscountCategoryFinder.class, times (1));
Spottende ugyldige metoder
Lad os først prøve at forstå, hvilken slags brugssager der kan være stubning af ugyldige metoder:
# 1) Metodeopkald for eksempel - der sender en e-mail-underretning under processen.
For eksempel :Antag at du ændrer din adgangskode til din internetbank-konto, når ændringen er vellykket, modtager du en besked via din e-mail.
Dette kan betragtes som / changePassword som et POST-opkald til Bank API, der inkluderer et ugyldigt metodeopkald til at sende en e-mail-underretning til kunden.
#to) Et andet almindeligt eksempel på det ugyldige metodeopkald er opdaterede anmodninger til en DB, der tager noget input og ikke returnerer noget.
Stubning af ugyldige metoder (dvs. de metoder, der ikke returnerer noget eller ellers kaster en undtagelse), kan håndteres ved hjælp af funktionerne doNothing (), doThrow () og doAnswer (), doCallRealMethod () . Det kræver, at stubben konfigureres ved hjælp af ovenstående metoder i henhold til testforventningerne.
Bemærk også, at alle de ugyldige metodeopkald som standard bespottes til doNothing (). Derfor, selvom en eksplicit mock-opsætning ikke udføres UGYLDIG metodeopkald er standardadfærden stadig at gøreNothing ().
Lad os se eksempler på alle disse funktioner:
Lad os antage, at der er en klasse for alle eksemplerne StudentScoreUpdates som har en metode calcularSumAndStore (). Denne metode beregner summen af scores (som input) og kalder a ugyldig metode updateScores () på databaseImplementation instans.
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 enhedstest til mock-metodeopkaldet med nedenstående eksempler:
# 1) gør Intet () - doNothing () er standardopførelsen for ugyldige metodeopkald i Mockito, dvs. selvom du bekræfter et opkald om ugyldig metode (uden eksplicit at oprette et tomrum til doNothing (), vil bekræftelsen stadig 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 anvendelser sammen med doNothing ()
til) Når den ugyldige metode kaldes flere gange, og du vil konfigurere forskellige svar til forskellige påkald, som - doNothing () til den første påkaldelse og kaste en undtagelse på den næste indkaldelse.
For eksempel :Konfigurer mock sådan:
Mockito. doNothing ().doThrow(new RuntimeException()).when(mockDatabase).updateScores( anyString (), anyInt ());
b) Når du vil fange de argumenter, som ugyldighedsmetoden blev kaldt til, skal ArgumentCaptor-funktionaliteten i Mockito bruges. Dette giver en ekstra verifikation af argumenter, som metoden blev kaldt 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 nyttigt, når du blot vil kaste en undtagelse, når ugyldighedsmetoden påberåbes fra den testede metode.
For eksempel:
Mockito.doThrow(newRuntimeException()).when(mockDatabase).updateScores ( anyString (), anyInt ());
# 3) doAnswer ()- doAnswer () giver simpelthen en grænseflade til at lave en brugerdefineret logik.
hvordan man åbner torrentede filer på Windows 10
For eksempel. Ændring af en værdi gennem de godkendte argumenter, returnering af brugerdefinerede værdier / data, som en normal stub ikke kunne have returneret specielt til ugyldige metoder.
Med henblik på demonstration - Jeg har stubbet metoden updateScores () ugyldig for at returnere en “ svar() ”Og udskriv værdien af et af de argumenter, der skulle have været sendt, da metoden skulle have været kaldt.
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 stubs (hvor du kan kalde virkelige metoder til nogle af metoderne og stub ud resten).
For ugyldige metoder giver mockito en speciel funktion kaldet doCallRealMethod (), som kan bruges, når du prøver at opsætte mocken. Hvad dette vil gøre, er at kalde den virkelige ugyldighedsmetode med de faktiske argumenter.
For eksempel:
Mockito. doCallRealMethod ().when(mockDatabaseImpl).updateScores( anyString (), anyInt ());
Tips og tricks
# 1) Inkluderet flere statiske klasser i den samme testmetode / klasse- Brug af PowerMockito hvis der er behov for at spotte flere statiske af afsluttende klasser, så klassens navne i @ ForberedForTest kommentar kan nævnes som komma-adskilt værdi som en matrix (den accepterer i det væsentlige en matrix af klassens navne).
Eksempel:
@PrepareForTest({PriceCalculator.class, DiscountCategoryFinder.class})
Som vist i eksemplet ovenfor antager du, at både PriceCalculator og DiscountCategoryFinder er endelige klasser, der skal bespottes. Begge disse kan nævnes som en række klasser i PrepareForTest-kommentar og kan stubbes i testmetoden.
# 2) PrepareForTest attribut Positionering - Placeringen af denne attribut er vigtig med hensyn til den type test, der er inkluderet i testklassen.
Hvis alle testene skal bruge den samme endelige klasse, er det fornuftigt at nævne denne attribut på testklasseniveau, hvilket simpelthen betyder, at den forberedte klasse vil være tilgængelig for alle testmetoder. I modsætning til dette, hvis kommentaren er nævnt i testmetoden, vil den kun være tilgængelig for de bestemte tests
Konklusion
I denne vejledning diskuterede vi forskellige tilgange til at spotte statiske, endelige og ugyldige metoder.
Selvom brug af mange statiske eller endelige metoder forhindrer testbarhed, og der stadig er support til rådighed til test / mocking for at hjælpe med at skabe enhedstest for at opnå større tillid til koden / applikationen selv for ældre kode, som generelt ikke er vant til være designet til testbarhed.
Til statiske og endelige metoder har Mockito ikke understøttelse uden for boksen, men biblioteker som PowerMockito (som stærkt arver mange ting fra Mockito) yder sådan support og skal faktisk udføre bytecode-manipulation for at understøtte disse funktioner.
Mockito out of the box understøtter stubbing ugyldige metoder og giver forskellige metoder som doNothing, doAnswer, doThrow, doCallRealMethod osv. Og kan bruges i henhold til testets krav.
Ofte stillede spørgsmål om Mockito Interview er orienteret i vores næste vejledning.
PREV-vejledning | NÆSTE vejledning
Anbefalet læsning
- Mockito Tutorial: Mockito Framework for Mocking i Unit Testing
- Top 12 Mockito Interview Spørgsmål (Mocking Framework Interview)
- Statisk i C ++
- Java-tråde med metoder og livscyklus
- Oprettelse af Mocks and Spies i Mockito med kodeeksempler
- Forskellige typer matchere leveret af Mockito
- Metoder og teknikker til forebyggelse af defekter
- Sådan bruges metoder i SoapUI til udførelse af bulk-test - SoapUI Tutorial # 10