Verschil tussen when () en doXxx () -methoden in Mockito

1. Inleiding

Mockito is een populair Java-spotraamwerk. Hiermee is het eenvoudig om nep-objecten te maken, nepgedrag te configureren, methode-argumenten vast te leggen en interacties met nep-objecten te verifiëren.

Nu zullen we ons concentreren op het specificeren van schijngedrag. We hebben twee manieren om dat te doen: de wanneer (). thenDoSomething () en de doSomething (). when () syntaxis.

In deze korte tutorial zullen we zien waarom we ze allebei hebben.

2. wanneer() Methode

Laten we eens kijken naar het volgende Werknemer koppel:

interface Werknemer {String greet (); ongeldig werk (DayOfWeek-dag); }

In onze tests gebruiken we een mock-up van deze interface. Laten we zeggen dat we de mock's willen configureren begroeten() methode om de string te retourneren "Hallo". Het is eenvoudig om dit te doen met behulp van Mockito's wanneer() methode:

@Test ongeldig gegevenNonVoidMethod_callingWhen_shouldConfigureBehavior () {// gegeven wanneer (employee.greet ()). ThenReturn ("Hallo"); // when String-begroeting = employee.greet (); // dan assertThat (groet, is ("Hallo")); }

Wat gebeurt er? De werknemer object is een schijnvertoning. Wanneer we een van zijn methoden aanroepen, registreert Mockito die aanroep. Met de oproep van de wanneer() methode, weet Mockito dat deze aanroep geen interactie was door de bedrijfslogica. Het was een verklaring dat we wat gedrag aan het nepobject willen toewijzen. Daarna met een van de thenXxx () methoden specificeren we het verwachte gedrag.

Tot nu toe is het een goede oude spot. Evenzo willen we het werk() methode om een ​​uitzondering te genereren, wanneer we het noemen met een argument van zondag:

@Test ongeldig gegevenVoidMethod_callingWhen_wontCompile () {// gegeven wanneer (employee.work (DayOfWeek.SUNDAY)). ThenThrow (nieuwe IAmOnHolidayException ()); // wanneer Uitvoerbaar workCall = () -> employee.work (DayOfWeek.SUNDAY); // dan assertThrows (IAmOnHolidayException.class, workCall); }

Helaas kan deze code niet worden gecompileerd, omdat in de werk (werknemer.werk (...)) bel de werk() methode heeft een leegte retourtype; daarom kunnen we het niet in een andere methodeaanroep verpakken. Betekent dit dat we ongeldige methoden niet kunnen bespotten? Natuurlijk kunnen we. doXxx methoden om te redden!

3. doXxx () Methoden

Laten we eens kijken hoe we de exception throwing kunnen configureren met de doThrow () methode:

@Test ongeldig gegevenVoidMethod_callingDoThrow_shouldConfigureBehavior () {// gegeven doThrow (nieuwe IAmOnHolidayException ()). When (werknemer) .work (DayOfWeek.SUNDAY); // wanneer Uitvoerbaar workCall = () -> employee.work (DayOfWeek.SUNDAY); // dan assertThrows (IAmOnHolidayException.class, workCall); }

Deze syntaxis is iets anders dan de vorige: we proberen niet een leegte method call binnen een andere method call. Daarom compileert deze code.

Laten we eens kijken wat er net is gebeurd. Ten eerste hebben we aangegeven dat we een uitzondering willen maken. Vervolgens hebben we de wanneer() methode, en we passeerden het mock-object. Daarna hebben we gespecificeerd welk gedrag van nepinteractie we willen configureren.

Merk op dat dit niet hetzelfde is wanneer() methode die we eerder hebben gebruikt. Merk ook op dat we de nepinteractie hebben geketend na het aanroepen van wanneer(). Ondertussen hebben we het tussen haakjes gedefinieerd met de eerste syntaxis.

Waarom hebben we de eerste wanneer (). thenXxx (), wanneer het niet in staat is tot zo'n veelvoorkomende taak, zoals het configureren van een leegte aanroeping? Het heeft meerdere voordelen voor de doXxx (). wanneer () syntaxis.

Eerste, het is logischer voor ontwikkelaars om uitspraken te schrijven en te lezen als "bij enige interactie, doe dan iets" dan "doe iets, bij enige interactie".

Ten tweede kunnen we meerdere gedragingen toevoegen aan dezelfde interactie met chaining. Dat is omdat wanneer() geeft een instantie van de klasse terug Doorlopend Stubbing, dat is thenXxx () methoden retourneren hetzelfde type.

Aan de andere kant, doXxx () methoden retourneren een Stubber instantie, en Stubber.when (T mock) geeft terug T, zodat we kunnen specificeren wat voor soort methode-aanroep we willen configureren. Maar T maakt bijvoorbeeld deel uit van onze applicatie Werknemer in onze codefragmenten. Maar T zal geen Mockito-klasse retourneren, dus we kunnen niet meerdere gedragingen toevoegen met chaining.

4. BDDMockito

BDDMockito gebruikt een alternatieve syntaxis voor degene die we hebben behandeld. Het is vrij eenvoudig: in onze nepconfiguraties moeten we het trefwoord 'wanneer" naar "gegeven'En het zoekwoord'Doen" naar "zullen“. Verder blijft onze code hetzelfde:

@Test ongeldig gegevenNonVoidMethod_callingGiven_shouldConfigureBehavior () {// gegeven gegeven (employee.greet ()). WillReturn ("Hallo"); // when String-begroeting = employee.greet (); // dan assertThat (groet, is ("Hallo")); } @Test void givenVoidMethod_callingWillThrow_shouldConfigureBehavior () {// gegeven willThrow (nieuwe IAmOnHolidayException ()). Gegeven (medewerker). Werk (DayOfWeek.SUNDAY); // wanneer Uitvoerbaar workCall = () -> employee.work (DayOfWeek.SUNDAY); // dan assertThrows (IAmOnHolidayException.class, workCall); }

5. Conclusie

We zagen de voor- en nadelen van het configureren van een mock-object de wanneer (). thenXxx () of de doXxx (). wanneer () manier. We hebben ook gezien hoe deze syntaxis werken en waarom we beide hebben.

Zoals gewoonlijk zijn de voorbeelden beschikbaar op GitHub.