Mockito - Mit Spionen

1. Übersicht

In diesem Tutorial zeigen wir, wie Sie Spione in Mockito optimal nutzen können .

Wir werden über die @ Spy- Annotation sprechen , wie man einen Spion stoppt und schließlich - wir werden auf den Unterschied zwischen Mock und Spy eingehen .

Und natürlich, um mehr Mockito-Güte zu erfahren, schauen Sie sich die Serie hier an.

2. Einfaches Spy Beispiel

Beginnen wir mit einem einfachen Beispiel für die Verwendung eines Spions .

Einfach ausgedrückt ist die API Mockito.spy () - um ein reales Objekt auszuspionieren .

Auf diese Weise können wir alle normalen Methoden des Objekts aufrufen und gleichzeitig jede Interaktion verfolgen, genau wie bei einem Mock.

OK, machen wir ein kurzes Beispiel, in dem wir ein vorhandenes ArrayList- 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, wie die reale Methode add () tatsächlich aufgerufen wird und wie die Größe von spyList 2 wird.

3. Die @ Spy- Anmerkung

Weiter - sehen wir uns an, wie die Annotation @Spy verwendet wird . Wir können @Spy Annotation anstelle von spy () 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()); }

Um die Mockito-Annotation zu aktivieren (z. B. @Spy , @Mock ,…), müssen Sie einen der folgenden Schritte ausführen :

  • Rufen Sie die Methode MockitoAnnotations.initMocks (this) auf, um mit Anmerkungen versehene Felder zu initialisieren
  • Verwenden Sie den integrierten Runner @RunWith (MockitoJUnitRunner.class)

4. Einen Spion stubben

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

Im folgenden Beispiel verwenden wir doReturn () , um die size () -Methode 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 zwischen Mock und Spy in Mockito diskutieren - nicht die theoretischen Unterschiede zwischen den beiden Konzepten, sondern nur, wie sie sich in Mockito selbst unterscheiden.

Wenn Mockito ein Modell erstellt, geschieht dies aus der Klasse eines Typs und nicht aus einer tatsächlichen Instanz. Der Mock erstellt einfach eine Bare-Bones-Shell-Instanz der Klasse, die vollständig instrumentiert ist, um Interaktionen mit ihr zu verfolgen.

Auf der anderen Seite wird der Spion eine vorhandene Instanz umschließen . Es verhält sich immer noch genauso wie die normale Instanz - der einzige Unterschied besteht darin, dass es auch instrumentiert wird, um alle Interaktionen mit ihm zu verfolgen.

Im folgenden Beispiel erstellen wir ein Modell der ArrayList- Klasse:

@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 der add- 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. Grundlegendes zur Mockito NotAMockException

In diesem letzten Abschnitt erfahren Sie mehr über die Mockito NotAMockException . Diese Ausnahme ist eine der häufigsten Ausnahmen, auf die wir wahrscheinlich stoßen werden, wenn wir Spott oder Spion missbrauchen .

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 ist aus der Mockito-Fehlermeldung ziemlich klar, wo das Problem liegt. In unserem Beispiel ist die Liste ist Objekt kein Mock. Die Mockito when () -Methode erwartet ein Schein- oder Spionageobjekt als Argument .

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

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 jetzt wie erwartet und wir sehen die Mockito NotAMockException 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 einen Spion erstellt , wie man die @ Spy- Annotation verwendet, wie man einen Spion stubbt und schließlich - den Unterschied zwischen Mock und Spy .

Die Implementierung all dieser Beispiele finden Sie auf GitHub .

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

Und natürlich, um mehr Mockito-Güte zu erfahren, schauen Sie sich die Serie hier an.