Inleiding tot PowerMock

1. Overzicht

Unit-testing met behulp van een mocking-framework wordt al lang erkend als een nuttige praktijk, en met name het Mockito-framework heeft de afgelopen jaren deze markt gedomineerd.

En om fatsoenlijke code-ontwerpen mogelijk te maken en de openbare API eenvoudig te maken, zijn sommige gewenste functies opzettelijk weggelaten. In sommige gevallen dwingen deze tekortkomingen testers echter om omslachtige code te schrijven, alleen maar om het maken van spot mogelijk te maken.

Dit is waar het PowerMock-framework in het spel komt.

PowerMockito is een PowerMock-extensie-API om Mockito te ondersteunen. Het biedt mogelijkheden om op een eenvoudige manier met de Java Reflection API te werken om de problemen van Mockito op te lossen, zoals het gebrek aan mogelijkheid om definitieve, statische of privémethoden te bespotten.

Deze tutorial geeft een inleiding tot de PowerMockito API en hoe deze wordt toegepast in tests.

2. Voorbereiden op testen met PowerMockito

De eerste stap om PowerMock-ondersteuning voor Mockito te integreren, is om de volgende twee afhankelijkheden op te nemen in het Maven POM-bestand:

 org.powermock powermock-module-junit4 1.6.4 test org.powermock powermock-api-mockito 1.6.4 test 

Vervolgens moeten we onze testcases voorbereiden om mee te werken PowerMockito door de volgende twee annotaties toe te passen:

@RunWith (PowerMockRunner.class) @PrepareForTest (fullyQualifiedNames = "com.baeldung.powermockito.introduction. *")

De FullyQualifiedNames element in het @BuienRadarNL annotatie vertegenwoordigt een reeks volledig gekwalificeerde namen van typen die we willen bespotten. In dit geval gebruiken we een pakketnaam met een jokerteken om te vertellen PowerMockito om alle soorten binnen de com.baeldung.powermockito.introductie pakket om te bespotten.

Nu zijn we klaar om de kracht van PowerMockito.

3. Spottende constructeurs en definitieve methoden

In deze sectie zullen we de manieren demonstreren om een ​​nepinstantie te krijgen in plaats van een echte bij het instantiëren van een klasse met de nieuw operator en gebruik dat object vervolgens om een ​​laatste methode te bespotten. De samenwerkende klasse, waarvan de constructors en de uiteindelijke methoden worden bespot, wordt als volgt gedefinieerd:

openbare klasse CollaboratorWithFinalMethods {openbare laatste String helloMethod () {retourneer "Hallo wereld!"; }}

Eerst maken we een mock-object met behulp van de PowerMockito API:

CollaboratorWithFinalMethods mock = mock (CollaboratorWithFinalMethods.class);

Stel vervolgens een verwachting in die zegt dat wanneer de constructor no-arg van die klasse wordt aangeroepen, een nepinstantie moet worden geretourneerd in plaats van een echte:

whenNew (CollaboratorWithFinalMethods.class) .withNoArguments (). thenReturn (mock);

Laten we eens kijken hoe deze constructie-bespotting in actie werkt door het instantiëren van de CollaboratorWithFinalMethods class met behulp van de standaardconstructor en verifieer vervolgens het gedrag van PowerMock:

CollaboratorWithFinalMethods medewerker = nieuwe CollaboratorWithFinalMethods (); verifiërenNew (CollaboratorWithFinalMethods.class) .withNoArguments ();

In de volgende stap wordt een verwachting gesteld aan de uiteindelijke methode:

when (collaborator.helloMethod ()). thenReturn ("Hallo Baeldung!");

Deze methode wordt vervolgens uitgevoerd:

String welkom = collaborator.helloMethod ();

De volgende beweringen bevestigen dat het halloMethod methode is aangeroepen op de medewerker object, en retourneert de waarde die is ingesteld door de bespottende verwachting:

Mockito.verify (medewerker) .helloMethod (); assertEquals ("Hallo Baeldung!", welkom);

Als we een specifieke laatste methode willen bespotten in plaats van alle laatste in een object, dan is de Mockito.spy (T-object) methode kan van pas komen. Dit wordt geïllustreerd in sectie 5.

4. Spottende statische methoden

Stel dat we statische methoden van een klasse met de naam CollaboratorWithStaticMethods. Deze klasse wordt als volgt verklaard:

openbare klasse CollaboratorWithStaticMethods {openbare statische tekenreeks firstMethod (tekenreeksnaam) {retourneer "Hallo" + naam + "!"; } public static String secondMethod () {return "Hallo niemand!"; } public static String thirdMethod () {return "Hallo weer niemand!"; }}

Om deze statische methoden te bespotten, moeten we de omsluitende klasse registreren met de PowerMockito API:

mockStatic (CollaboratorWithStaticMethods.class);

Als alternatief kunnen we de Mockito.spy (Klasse) methode om een ​​specifieke te bespotten, zoals aangetoond in de volgende sectie.

Vervolgens kunnen verwachtingen worden ingesteld om de waarden te definiëren die methoden moeten retourneren wanneer ze worden aangeroepen:

when (CollaboratorWithStaticMethods.firstMethod (Mockito.anyString ())) .thenReturn ("Hallo Baeldung!"); when (CollaboratorWithStaticMethods.secondMethod ()). thenReturn ("Niets bijzonders");

Of er kan een uitzondering worden ingesteld om te worden gegenereerd bij het aanroepen van de derde methode methode:

doThrow (nieuwe RuntimeException ()). when (CollaboratorWithStaticMethods.class); CollaboratorWithStaticMethods.thirdMethod ();

Nu is het tijd om de eerste twee methoden uit te voeren:

String firstWelcome = CollaboratorWithStaticMethods.firstMethod ("Whoever"); String secondWelcome = CollaboratorWithStaticMethods.firstMethod ("Whatever");

In plaats van leden van de echte klasse op te roepen, worden de bovenstaande aanroepen gedelegeerd naar de methoden van de mock. De volgende beweringen bewijzen dat de mock in werking is getreden:

assertEquals ("Hallo Baeldung!", firstWelcome); assertEquals ("Hallo Baeldung!", secondWelcome);

We zijn ook in staat om het gedrag van de mock-methoden te verifiëren, inclusief hoe vaak een methode wordt aangeroepen. In dit geval is het eerste methode is twee keer gebeld, terwijl de secondMethod heeft nooit:

verifiërenStatic (Mockito.times (2)); CollaboratorWithStaticMethods.firstMethod (Mockito.anyString ()); verifiërenStatic (Mockito.never ()); CollaboratorWithStaticMethods.secondMethod ();

Opmerking: De verifiërenStatic methode moet worden aangeroepen vlak voordat een statische methode wordt geverifieerd voor PowerMockito om te weten dat de aanroep van de opeenvolgende methode moet worden geverifieerd.

Ten slotte, de statische derde methode methode moet een RuntimeException zoals eerder verklaard op de mock. Het wordt gevalideerd door het verwacht element van de @Test annotatie:

@Test (verwacht = RuntimeException.class) openbare leegte gegevenStaticMethods_whenUsingPowerMockito_thenCorrect () {// andere methoden CollaboratorWithStaticMethods.thirdMethod (); }

5. Gedeeltelijk bespotten

In plaats van een hele klas te bespotten, de PowerMockito API maakt het mogelijk om een ​​deel ervan te bespotten met behulp van de spion methode. De volgende klasse wordt gebruikt als medewerker om de PowerMock-ondersteuning voor gedeeltelijk bespotten te illustreren:

openbare klasse CollaboratorForPartialMocking {openbare statische String staticMethod () {retourneer "Hallo Baeldung!"; } public final String finalMethod () {return "Hallo Baeldung!"; } private String privateMethod () {retourneer "Hallo Baeldung!"; } public String privateMethodCaller () {return privateMethod () + "Welkom in de Java-wereld."; }}

Laten we beginnen met het bespotten van een statische methode, die wordt genoemd staticMethod in de bovenstaande klassendefinitie. Gebruik eerst de PowerMockito API om het CollaboratorForPartialMocking class en stel een verwachting in voor zijn statische methode:

spion (CollaboratorForPartialMocking.class); when (CollaboratorForPartialMocking.staticMethod ()). thenReturn ("Ik ben een statische mock-methode.");

De statische methode wordt vervolgens uitgevoerd:

returnValue = CollaboratorForPartialMocking.staticMethod ();

Het spotgedrag wordt als volgt geverifieerd:

verifiërenStatic (); CollaboratorForPartialMocking.staticMethod ();

De volgende bewering bevestigt dat de mock-methode daadwerkelijk is aangeroepen door de geretourneerde waarde te vergelijken met de verwachting:

assertEquals ("Ik ben een statische mock-methode.", returnValue);

Nu is het tijd om over te gaan op de laatste en privémethoden. Om de gedeeltelijke bespotting van deze methoden te illustreren, moeten we de klasse instantiëren en de PowerMockito API naar spion het:

CollaboratorForPartialMocking medewerker = nieuwe CollaboratorForPartialMocking (); CollaboratorForPartialMocking mock = spy (medewerker);

De hierboven gemaakte objecten worden gebruikt om het bespotten van zowel de laatste als de privémethoden te demonstreren. We zullen nu de laatste methode behandelen door een verwachting te stellen en de methode aan te roepen:

when (mock.finalMethod ()). thenReturn ("Ik ben een laatste mock-methode."); returnValue = mock.finalMethod ();

Het gedrag van het gedeeltelijk bespotten van die methode is bewezen:

Mockito.verify (mock) .finalMethod ();

Een test verifieert dat het aanroepen van het finalMethod methode retourneert een waarde die overeenkomt met de verwachting:

assertEquals ("Ik ben een laatste mock-methode.", returnValue);

Een soortgelijk proces wordt toegepast op de privémethode. Het belangrijkste verschil is dat we deze methode niet rechtstreeks vanuit de testcase kunnen oproepen. In principe moet een privé-methode worden aangeroepen door anderen uit dezelfde klasse. In de CollaboratorForPartialMocking klasse, de privateMethod methode moet worden aangeroepen door de privateMethodCaller methode en we zullen de laatste gebruiken als afgevaardigde. Laten we beginnen met de verwachting en aanroep:

when (mock, "privateMethod"). thenReturn ("Ik ben een private mock-methode."); returnValue = mock.privateMethodCaller ();

De bespotting van de privémethode wordt bevestigd:

verifieerPrivate (mock) .invoke ("privateMethod");

De volgende test zorgt ervoor dat de geretourneerde waarde van het aanroepen van de privémethode hetzelfde is als de verwachting:

assertEquals ("Ik ben een privé-mock-methode. Welkom in de Java-wereld.", returnValue);

6. Conclusie

Deze tutorial heeft een inleiding gegeven tot het PowerMockito API, waarmee het gebruik ervan wordt aangetoond bij het oplossen van enkele van de problemen die ontwikkelaars tegenkomen bij het gebruik van het Mockito-framework.

De implementatie van deze voorbeelden en codefragmenten is te vinden in het gekoppelde GitHub-project.