Mocking af private metoder ved hjælp af PowerMock

1. Oversigt

En af udfordringerne ved enhedstest er at håne private metoder.

I denne vejledning lærer vi om, hvordan vi kan opnå dette ved hjælp af PowerMock-biblioteket - som understøttes af JUnit og TestNG.

PowerMock integreres med mocking-rammer som EasyMock og Mockito og er beregnet til at tilføje yderligere funktionalitet til disse - såsom mocking af private metoder, afsluttende klasser og endelige metoder, etc.

Det gør det ved at stole på manipulation af bytecode og en helt separat classloader.

2. Maven-afhængigheder

Lad os først tilføje krævede afhængigheder for at bruge PowerMock med Mockito og JUnit til vores pom.xml:

 org.powermock powermock-module-junit4 1.7.3 test org.powermock powermock-api-mockito2 1.7.3 test 

De nyeste versioner kan kontrolleres her og her.

3. Eksempel

Lad os komme i gang med et eksempel på en LuckyNumberGenerator. Denne klasse har en enkelt offentlig metode til at generere et heldigt tal:

public int getLuckyNumber (String name) {saveIntoDatabase (name); if (name == null) {return getDefaultLuckyNumber (); } returner getComputedLuckyNumber (name.length ()); }

4. Variationer i hån af private metoder

For udtømmende enhedstest af metoden er vi nødt til at spotte private metoder.

4.1. Metode uden argumenter, men med returværdi

Lad os som et simpelt eksempel spotte opførelsen af ​​en privat metode uden argumenter og tvinge den til at returnere den ønskede værdi:

LuckyNumberGenerator mock = spion (ny LuckyNumberGenerator ()); når (mock, "getDefaultLuckyNumber"). derefter Retur (300); 

I dette tilfælde håner vi den private metode getDefaultLuckyNumber og få det til at returnere en værdi på 300.

4.2. Metode med argument og returværdi

Lad os derefter spotte opførelsen af ​​en privat metode med et argument og tvinge den til at returnere den ønskede værdi:

LuckyNumberGenerator mock = spion (ny LuckyNumberGenerator ()); doReturn (1) .when (mock, "getComputedLuckyNumber", ArgumentMatchers.anyInt ()); 

I dette tilfælde håner vi den private metode og får den til at returnere 1.

Bemærk, at vi ikke er ligeglade med inputargumentet og brugen ArgumentMatchers.anyInt () som et jokertegn.

4.3. Verifikation af påkaldelse af en metode

Vores endelige strategi er at bruge PowerMock til at verificere påkaldelsen af ​​en privat metode:

LuckyNumberGenerator mock = spion (ny LuckyNumberGenerator ()); int resultat = mock.getLuckyNumber ("Tyranosorøs"); verifyPrivate (mock) .invoke ("saveIntoDatabase", ArgumentMatchers.anyString ()); 

5. Et ord med forsigtighed

Endelig, selvom private metoder kan testes ved hjælp af PowerMock, vi skal være ekstra forsigtige, når vi bruger denne teknik.

Da hensigten med vores test er at validere en klasses opførsel, bør vi afstå fra at ændre klassens interne adfærd under enhedstest.

Spotteteknikker skal anvendes på klassens eksterne afhængigheder og ikke på selve klassen.

Hvis det er vigtigt at spotte private metoder til at teste vores klasser, indikerer det normalt et dårligt design.

6. Konklusion

I denne hurtige artikel viste vi, hvordan PowerMock kunne bruges til at udvide Mockitos evne til hån og verifikation af private metoder i den testede klasse.

Kildekoden til denne vejledning kan findes på GitHub.