JMockit 101

1. Inleiding

Met dit artikel beginnen we aan een nieuwe serie die is gecentreerd rond de mocking-toolkit JMockit.

In deze eerste aflevering zullen we het hebben over wat JMockit is, de kenmerken ervan en hoe er spotjes worden gemaakt en ermee worden gebruikt.

Latere artikelen zullen zich concentreren op en dieper ingaan op de mogelijkheden ervan.

2. JMockit

2.1. Invoering

Laten we eerst eens kijken wat JMockit is: een Java-framework voor het bespotten van objecten in tests (je kunt het gebruiken voor zowel JUnit- als TestNG-versies).

Het gebruikt Java's instrumentatie-API's om de bytecode van de klassen tijdens runtime te wijzigen om hun gedrag dynamisch te veranderen. Enkele van de sterke punten zijn de uitdrukbaarheid en het out-of-the-box vermogen om statische en privé-methoden te bespotten.

Misschien ben je nieuw bij JMockit, maar het is zeker niet omdat het nieuw is. De ontwikkeling van JMockit begon in juni 2006 en de eerste stabiele uitgave dateert van december 2012, dus het bestaat al een tijdje (de huidige versie is 1.24 op het moment dat het artikel werd geschreven).

2.2. Afhankelijkheid van Maven

Eerst moeten we de jmockit-afhankelijkheid aan ons project toevoegen:

 org.jmockit jmockit 1.41 

2.3. De uitdrukbaarheid van JMockit

Zoals eerder verteld, is een van de sterkste punten van JMockit de uitdrukbaarheid ervan. Om schijnvertoningen te creëren en hun gedrag te definiëren, in plaats van methoden aan te roepen vanuit de mocking-API, hoeft u ze alleen rechtstreeks te definiëren.

Dit betekent dat u geen dingen zult doen als:

API.expect (mockInstance.method ()). AndThenReturn (waarde) .times (2);

Verwacht in plaats daarvan dingen als:

nieuwe verwachting () {mockInstance.method (); resultaat = waarde; tijden = 2; }

Het lijkt misschien dat het meer code is, maar je zou alle drie de regels gewoon op één kunnen zetten. Het echt belangrijke deel is dat je niet eindigt met een grote "trein" van aaneengeschakelde methodeaanroepen. In plaats daarvan krijg je een definitie van hoe je wilt dat de mock zich gedraagt ​​wanneer hij wordt gebeld.

Als je daar rekening mee houdt op de resultaat = waarde deel dat je alles zou kunnen retourneren (vaste waarden, dynamisch gegenereerde waarden, uitzonderingen, enz.), wordt de expressiviteit van JMockit nog duidelijker.

2.4. Het Record-Replay-Verify-model

Tests met JMockit zijn onderverdeeld in drie gedifferentieerde fasen: opnemen, afspelen en verifiëren.

  1. Op de Vermelding fase, tijdens de testvoorbereiding en vóór de aanroepen van de methoden die we willen uitvoeren, zullen we het verwachte gedrag definiëren voor alle tests die tijdens de volgende fase zullen worden gebruikt.
  2. De herhaling fase is die waarin de te testen code wordt uitgevoerd. De aanroepen van bespotte methoden / constructors die eerder in de vorige fase zijn opgenomen, worden nu opnieuw afgespeeld.
  3. Ten slotte, op de verifiëren fase, zullen we beweren dat het resultaat van de test degene was die we verwachtten (en dat bespot zich gedroeg en werd gebruikt volgens wat was gedefinieerd in de opnamefase).

Met een codevoorbeeld zou een draadframe voor een test er ongeveer zo uitzien:

@Test public void testWireframe () {// voorbereidingscode niet specifiek voor JMockit, eventuele nieuwe Expectations () {{// definieer verwacht gedrag voor spot}}; // voer code uit onder test nieuwe Verificaties () {{// verifieer bespottingen}}; // beweringen}

3. Mocks creëren

3.1. Annotaties van JMockit

Als u JMockit gebruikt, is de gemakkelijkste manier om spot te gebruiken, het gebruik van annotaties. Er zijn er drie voor het maken van spot (@Mocked, @Injecteerbaar en @Capturing) en een om de klasse te specificeren die wordt getest (@Getest).

Bij gebruik van de @Mocked annotatie op een veld, zal het bespotte instanties creëren van elk nieuw object van die specifieke klasse.

Aan de andere kant, met de @Injecteerbaar annotatie, wordt er slechts één bespotte instantie gemaakt.

De laatste annotatie, @Capturing zal zich gedragen als @Gespot, maar zal zijn bereik uitbreiden tot elke subklasse die het type van het geannoteerde veld uitbreidt of implementeert.

3.2. Argumenten doorgeven aan tests

Bij het gebruik van JMockit is het mogelijk om spot als testparameters door te geven. Dit is erg handig voor het maken van een mock-up voor die ene test in het bijzonder, zoals een complex modelobject dat specifiek gedrag nodig heeft voor bijvoorbeeld één test. Het zou ongeveer zo zijn:

@RunWith (JMockit.class) openbare klasse TestPassingArguments {@Injectable privé Foo mockForEveryTest; @Getest privé Bar-bar; @Test openbare ongeldige testExample (@Mocked Xyz mockForJustThisTest) {nieuwe verwachtingen () {{mockForEveryTest.someMethod ("foo"); mockForJustThisTest.someOtherMethod (); }}; bar.codeUnderTest (); }}

Deze manier om een ​​mock te maken door het als een parameter door te geven, in plaats van een API-methode aan te roepen, toont ons opnieuw de uitdrukbaarheid waar we het vanaf het begin over hebben.

3.3. Compleet voorbeeld

Om dit artikel te beëindigen, zullen we een compleet voorbeeld van een test met JMockit opnemen.

In dit voorbeeld testen we een Uitvoerder klasse die gebruikmaakt van Medewerker in zijn uitvoeren() methode. Dit uitvoeren() methode, ontvangt een Model object als een parameter waaruit het zijn informatie verkrijgen() die een String retourneert, wordt deze String doorgegeven aan de samenwerken() methode van Medewerker dat zal terugkeren waar voor deze specifieke test, en deze waarde wordt doorgegeven aan de te ontvangen() methode van Medewerker.

Dus de geteste klassen zien er als volgt uit:

public class Model {public String getInfo () {return "info"; }} public class Collaborator {public boolean collaborate (String string) {return false; } openbare ongeldige ontvangst (boolean bool) {// NOOP}} openbare klasse Performer {privé-medewerker; public void perform (modelmodel) {booleaanse waarde = collaborator.collaborate (model.getInfo ()); collaborator.receive (waarde); }}

En de code van de test zal er als volgt uitzien:

@RunWith (JMockit.class) openbare klasse PerformerTest {@Injectable privé Collaborator-medewerker; @ Geteste privé performer; @Test public void testThePerformMethod (@Mocked Model model) {new Expectations () {{model.getInfo (); result = "bar"; collaborator.collaborate ("bar"); resultaat = waar; }}; performer.perform (model); nieuwe Verificaties () {{collaborator.receive (true); }}; }}

4. Conclusie

Hiermee sluiten we onze praktische introductie tot JMockit af. Als je meer wilt weten over JMockit, blijf dan op de hoogte voor toekomstige artikelen.

De volledige implementatie van deze tutorial is te vinden op het GitHub-project.

4.1. Artikelen in de serie

Alle artikelen uit de serie:

  • JMockit 101
  • A Guide to JMockit - Verwachtingen
  • JMockit geavanceerd gebruik

$config[zx-auto] not found$config[zx-overlay] not found