Kurzanleitung zu BDDMockito

1. Übersicht

Der BDD-Begriff wurde erstmals 2006 von Dan North geprägt.

BDD empfiehlt, Tests in einer natürlichen, für Menschen lesbaren Sprache zu schreiben, die sich auf das Verhalten der Anwendung konzentriert.

Es definiert eine klar strukturierte Schreibweise für Tests in drei Abschnitten (Anordnen, Handeln, Bestätigen):

  • gegeben einige Voraussetzungen (Arrange)
  • wenn eine Aktion stattfindet (Act)
  • Überprüfen Sie dann die Ausgabe (Assert)

Die Mockito-Bibliothek wird mit einer BDDMockito- Klasse geliefert , die BDD-freundliche APIs einführt. Diese API ermöglicht es uns, unsere Tests mit Given () BDD-freundlicher zu gestalten und mit then () Aussagen zu treffen .

In diesem Artikel erklären wir Ihnen, wie Sie unsere BDD-basierten Mockito-Tests einrichten. Wir werden auch über Unterschiede zwischen Mockito und BDDMockito APIs sprechen, um uns schließlich auf die BDDMockito API zu konzentrieren.

2. Setup

2.1. Maven-Abhängigkeiten

Die BDD- Variante von Mockito ist Teil der Mockito-Core- Bibliothek . Um loszulegen, müssen wir nur das Artefakt einschließen:

 org.mockito mockito-core 2.21.0 

Die neueste Version von Mockito finden Sie in Maven Central.

2.2. Importe

Unsere Tests können besser lesbar werden, wenn wir den folgenden statischen Import einbeziehen:

import static org.mockito.BDDMockito.*;

Beachten Sie, dass BDDMockito erstreckt Mockito , so werden wir nicht jede Funktion von der traditionellen zur Verfügung gestellt verpassen Mockito API.

3. Mockito gegen BDDMockito

Das traditionelle Verspotten in Mockito wird mit when (obj) durchgeführt . dann * () im Schritt Anordnen.

Später kann die Interaktion mit unserem Mock mit verify () im Assert-Schritt überprüft werden .

BDDMockito bietet BDD-Aliase für verschiedene Mockito- Methoden, sodass wir unseren Arrangierschritt mit angegeben (anstatt wann ) schreiben können. Ebenso können wir unseren Assert-Schritt mit then schreiben (anstatt zu überprüfen ).

Schauen wir uns ein Beispiel eines Testkörpers mit traditionellem Mockito an:

when(phoneBookRepository.contains(momContactName)) .thenReturn(false); phoneBookService.register(momContactName, momPhoneNumber); verify(phoneBookRepository) .insert(momContactName, momPhoneNumber);

Mal sehen, wie das im Vergleich zu BDDMockito ist :

given(phoneBookRepository.contains(momContactName)) .willReturn(false); phoneBookService.register(momContactName, momPhoneNumber); then(phoneBookRepository) .should() .insert(momContactName, momPhoneNumber);

4. Verspotten mit BDDMockito

Lassen Sie uns versuchen , das testen PhoneBookService , wo wir das verspotten benötigen PhoneBookRepository:

public class PhoneBookService { private PhoneBookRepository phoneBookRepository; public void register(String name, String phone) { if(!name.isEmpty() && !phone.isEmpty() && !phoneBookRepository.contains(name)) { phoneBookRepository.insert(name, phone); } } public String search(String name) { if(!name.isEmpty() && phoneBookRepository.contains(name)) { return phoneBookRepository.getPhoneNumberByContactName(name); } return null; } }

Mit BDDMockito als Mockito können wir einen Wert zurückgeben, der fest oder dynamisch sein kann. Es würde uns auch erlauben, eine Ausnahme zu werfen:

4.1. Rückgabe eines festen Wertes

Mit BDDMockito können wir Mockito problemlos so konfigurieren, dass bei jedem Aufruf unserer Zielmethode für Scheinobjekte ein festes Ergebnis zurückgegeben wird:

given(phoneBookRepository.contains(momContactName)) .willReturn(false); phoneBookService.register(xContactName, ""); then(phoneBookRepository) .should(never()) .insert(momContactName, momPhoneNumber);

4.2. Rückgabe eines dynamischen Werts

Mit BDDMockito können wir eine differenziertere Methode zur Rückgabe von Werten bereitstellen. Wir könnten ein dynamisches Ergebnis basierend auf der Eingabe zurückgeben:

given(phoneBookRepository.contains(momContactName)) .willReturn(true); given(phoneBookRepository.getPhoneNumberByContactName(momContactName)) .will((InvocationOnMock invocation) -> invocation.getArgument(0).equals(momContactName) ? momPhoneNumber : null); phoneBookService.search(momContactName); then(phoneBookRepository) .should() .getPhoneNumberByContactName(momContactName); 

4.3. Eine Ausnahme auslösen

Mockito zu sagen, dass er eine Ausnahme auslösen soll, ist ziemlich einfach:

given(phoneBookRepository.contains(xContactName)) .willReturn(false); willThrow(new RuntimeException()) .given(phoneBookRepository) .insert(any(String.class), eq(tooLongPhoneNumber)); try { phoneBookService.register(xContactName, tooLongPhoneNumber); fail("Should throw exception"); } catch (RuntimeException ex) { } then(phoneBookRepository) .should(never()) .insert(momContactName, tooLongPhoneNumber);

Beachten Sie, wie wir die Positionen von Given und Will * ausgetauscht haben. Dies ist obligatorisch, wenn wir eine Methode verspotten, die keinen Rückgabewert hat.

Beachten Sie auch, dass wir Argument-Matcher wie ( any , eq ) verwendet haben, um eine allgemeinere Methode zum Verspotten basierend auf Kriterien bereitzustellen, anstatt von einem festen Wert abhängig zu sein.

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir besprochen, wie BDDMockito versucht, eine BDD-Ähnlichkeit mit unseren Mockito-Tests herzustellen, und wir haben einige der Unterschiede zwischen Mockito und BDDMockito besprochen .

Der Quellcode befindet sich wie immer auf GitHub - im Testpaket com.baeldung.bddmockito .