Mockito - Mit Spionen

Mockito - Mit Spionen

1. Überblick

In diesem Tutorial zeigen wir Ihnen, wie Siespies in Mockito optimal nutzen können.

Wir werden über die Annotation von@Spyprechen, wie man einen Spion stoppt und schließlich - wir werden auf die Differenz zwischenMock undSpy eingehen.

Und natürlich für mehr Mockito-Gütehave a look at the series here.

Weitere Lektüre:

Mockito Verify Kochbuch

Mockito VerifyBeispiele, Verwendung und Best Practices.

Read more

Injizieren von Mockito Mocks in Frühlingsbohnen

Dieser Artikel zeigt, wie Sie mithilfe der Abhängigkeitsinjektion Mockito-Mocks in Spring Beans für Komponententests einfügen können.

Read more

Mockito Mock Methoden

Dieses Tutorial zeigt verschiedene Anwendungen der statischen Standard-Mock-Methoden der Mockito-API.

Read more

2. EinfachesSpy Beispiel

Beginnen wir mit einem einfachen Beispiel fürhow to use a spy.

Einfach ausgedrückt ist die APIMockito.spy() - bisspy on a real object.

Auf diese Weise können wir alle normalen Methoden des Objekts aufrufen und trotzdem jede Interaktion verfolgen, so wie wir es mit einem Mock tun würden.

OK, machen wir ein kurzes Beispiel, in dem wir ein vorhandenesArrayList-Objekt ausspionieren:

@Test
public void whenSpyingOnList_thenCorrect() {
    List list = new ArrayList();
    List spyList = Mockito.spy(list);

    spyList.add("one");
    spyList.add("two");

    Mockito.verify(spyList).add("one");
    Mockito.verify(spyList).add("two");

    assertEquals(2, spyList.size());
}

Beachten Sie, wiethe real method add() is actually called und wie die Größe vonspyList 2 wird.

3. Die Annotation@Spy

Weiter - sehen wir uns an, wie die Annotation@Spyverwendet wird. Wir können die Annotation@Spy anstelle vonspy() wie im folgenden Beispiel verwenden:

@Spy
List spyList = new ArrayList();

@Test
public void whenUsingTheSpyAnnotation_thenObjectIsSpied() {
    spyList.add("one");
    spyList.add("two");

    Mockito.verify(spyList).add("one");
    Mockito.verify(spyList).add("two");

    assertEquals(2, spyList.size());
}

Umenable Mockito annotation (wie@Spy,@Mock,…) zu erreichen, müssen wir einen der folgenden Schritte ausführen:

  • Rufen Sie die MethodeMockitoAnnotations.initMocks(this) auf, um mit Anmerkungen versehene Felder zu initialisieren

  • Verwenden Sie den eingebauten Läufer@RunWith(MockitoJUnitRunner.class)

4. Stubbing aSpy

Jetzt - Mal sehen, wie man einSpy stoppt. Wir können das Verhalten einer Methode mit der gleichen Syntax konfigurieren / überschreiben, die wir mit einem Mock verwenden würden.

Im folgenden Beispiel verwenden wirdoReturn(), um die Methodesize() zu überschreiben:

@Test
public void whenStubASpy_thenStubbed() {
    List list = new ArrayList();
    List spyList = Mockito.spy(list);

    assertEquals(0, spyList.size());

    Mockito.doReturn(100).when(spyList).size();
    assertEquals(100, spyList.size());
}

5. Mock vs. Spy in Mockito

Lassen Sie uns nun den Unterschied zwischenMock undSpy in Mockito diskutieren - nicht die theoretischen Unterschiede zwischen den beiden Konzepten, sondern nur, wie sie sich in Mockito selbst unterscheiden.

Wenn Mockito ein Mock erstellt, geschieht dies ausClass eines Typs, nicht aus einer tatsächlichen Instanz. Der Mock erstellt einfacha bare-bones shell instance der Klasse, die vollständig instrumentiert sind, um Interaktionen mit ihr zu verfolgen.

Andererseits istthe spy will wrap an existing instance. Es verhält sich immer noch so wie in der normalen Instanz - der einzige Unterschied besteht darin, dass es auch instrumentiert wird, um alle Interaktionen mit ihm zu verfolgen.

Im folgenden Beispiel erstellen wirmock der KlasseArrayList:

@Test
public void whenCreateMock_thenCreated() {
    List mockedList = Mockito.mock(ArrayList.class);

    mockedList.add("one");
    Mockito.verify(mockedList).add("one");

    assertEquals(0, mockedList.size());
}

Wie wir sehen können, fügt das Hinzufügen eines Elements zur verspotteten Liste eigentlich nichts hinzu - es ruft nur die Methode ohne andere Nebenwirkungen auf.

Ein Spion hingegen verhält sich anders - er ruft tatsächlich die eigentliche Implementierung deradd-Methode auf und fügt das Element der zugrunde liegenden Liste hinzu:

@Test
public void whenCreateSpy_thenCreate() {
    List spyList = Mockito.spy(new ArrayList());

    spyList.add("one");
    Mockito.verify(spyList).add("one");

    assertEquals(1, spyList.size());
}

6. MockitoNotAMockException verstehen

In diesem letzten Abschnitt lernen wir die MockitoNotAMockExceptionkennen. This exception is one of the common exceptions we will likely encounter when misusing mocks or spies.

Beginnen wir damit, zu sehen, unter welchen Umständen diese Ausnahme auftreten kann:

List list = new ArrayList();
Mockito.doReturn(100).when(list).size();

assertEquals("Size should be 100: ", 100, list.size());

Wenn wir dieses Code-Snippet ausführen, wird der folgende Fehler angezeigt:

org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
    doThrow(new RuntimeException()).when(mock).someMethod();

Zum Glück geht aus der Mockito-Fehlermeldung ganz klar hervor, wo das Problem liegt. In unserem Beispiel ist das Objektlistkein Mock. The Mockito when() method expects a mock or spy object as the argument.

Wie wir auch sehen können, beschreibt die Exception-Nachricht sogar, wie ein korrekter Aufruf aussehen sollte. Nachdem wir das Problem besser verstanden haben, beheben wir es gemäß der Empfehlung:

final List spyList = Mockito.spy(new ArrayList());
Mockito.doReturn(100).when(spyList).size();

assertEquals("Size should be 100: ", 100, spyList.size());

Unser Beispiel verhält sich nun wie erwartet und wir sehen die MockitoNotAMockException. nicht mehr

7. Fazit

In diesem kurzen Artikel haben wir die nützlichsten Beispiele für die Verwendung von Mockito-Spionen besprochen.

Wir haben gelernt, wie man einspy erstellt, wie man@Spy Annotation verwendet, wie man einspy stoppt und schließlich - die Differenz zwischenMock undSpy.

Die Implementierung all dieser Beispielecan be found over on GitHub.

Dies ist ein Maven-Projekt, daher sollte es einfach zu importieren und auszuführen sein.

Und natürlich für mehr Mockito-Gütehave a look at the series here.