Mockito - Ich verstehe, dass ein Spion die realen Methoden für ein Objekt aufruft, während ein Mock Methoden für das Doppelobjekt aufruft. Auch Spione sind zu vermeiden, es sei denn, es riecht nach Code. Wie funktionieren Spione und wann sollte ich sie tatsächlich benutzen? Wie unterscheiden sie sich von Mocks?
95
Antworten:
Technisch gesehen sind sowohl "Mocks" als auch "Spies" eine besondere Art von "Test-Doubles".
Mockito macht die Unterscheidung leider komisch.
Ein Mock in Mockito ist ein normales Mock in anderen Mocking-Frameworks (ermöglicht es Ihnen, Aufrufe zu stubben, dh bestimmte Werte aus Methodenaufrufen zurückzugeben).
Ein Spion in Mockito ist ein Teil-Mock in anderen Mocking-Frameworks (ein Teil des Objekts wird verspottet und ein Teil verwendet echte Methodenaufrufe).
quelle
Beide können verwendet werden, um Methoden oder Felder zu verspotten. Der Unterschied besteht darin, dass Sie im Mock ein vollständiges Mock- oder Fake-Objekt erstellen, während Sie im Spion das reale Objekt haben und nur bestimmte Methoden ausspionieren oder stubben.
Da es sich bei Spionageobjekten natürlich um eine echte Methode handelt, wird das echte Methodenverhalten aufgerufen, wenn Sie die Methode nicht stubben. Wenn Sie die Methode ändern und verspotten möchten, müssen Sie sie stubben.
Betrachten Sie das folgende Beispiel als Vergleich.
Wann solltest du Mock oder Spion benutzen? Wenn Sie sicher sein und vermeiden möchten, externe Dienste anzurufen, und nur die Logik im Gerät testen möchten, verwenden Sie mock. Wenn Sie einen externen Dienst aufrufen und einen Aufruf mit echten Abhängigkeiten ausführen oder einfach sagen möchten, dass Sie das Programm so ausführen möchten, wie es ist, und nur bestimmte Methoden stubben möchten, verwenden Sie spy. Das ist also der Unterschied zwischen Spion und Mock in Mockito.
quelle
TL; DR-Version,
Mit mock wird eine Bare-Bone-Shell-Instanz für Sie erstellt.
Mit Spy können Sie eine vorhandene Instanz teilweise verspotten
Typischer Anwendungsfall für Spy: Die Klasse verfügt über einen parametrisierten Konstruktor. Sie möchten zuerst das Objekt erstellen.
quelle
Ich habe hier ein ausführbares Beispiel erstellt: https://www.surasint.com/mockito-with-spy/
Ich kopiere etwas davon hier.
Wenn Sie so etwas wie diesen Code haben:
Möglicherweise benötigen Sie keinen Spion, da Sie sich nur über DepositMoneyService und WithdrawMoneyService lustig machen können.
Bei einigen Legacy-Codes besteht die Abhängigkeit im Code wie folgt:
Ja, Sie können zum ersten Code wechseln, aber dann wird die API geändert. Wenn diese Methode von vielen Orten verwendet wird, müssen Sie alle ändern.
Alternativ können Sie die Abhängigkeit folgendermaßen extrahieren:
Dann können Sie den Spion verwenden, um die Abhängigkeit wie folgt zu injizieren:
Weitere Details im obigen Link.
quelle
Der beste Ausgangspunkt sind wahrscheinlich die Dokumente für Mockito .
Generell können Sie mit dem Mockito-Mock Stubs erstellen.
Sie würden eine Stub-Methode erstellen, wenn diese Methode beispielsweise eine teure Operation ausführt. Angenommen, es wird eine Datenbankverbindung hergestellt, ein Wert aus der Datenbank abgerufen und an den Aufrufer zurückgegeben. Das Herstellen der Datenbankverbindung kann 30 Sekunden dauern und die Testausführung bis zu dem Punkt verlangsamen, an dem Sie wahrscheinlich den Kontext wechseln (oder den Test nicht mehr ausführen).
Wenn sich die zu testende Logik nicht um die Datenbankverbindung kümmert, können Sie diese Methode durch einen Stub ersetzen, der einen fest codierten Wert zurückgibt.
Mit dem Mockito-Spion können Sie überprüfen, ob eine Methode andere Methoden aufruft. Dies kann sehr nützlich sein, wenn Sie versuchen, Legacy-Code zu testen.
Es ist nützlich, wenn Sie eine Methode testen, die Nebenwirkungen wirkt, dann würden Sie einen Mockito-Spion verwenden. Dadurch werden Aufrufe an das reale Objekt delegiert und Sie können den Methodenaufruf, die Häufigkeit des Aufrufs usw. überprüfen.
quelle
Ich mag die Einfachheit dieser Empfehlung:
Quelle: https://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/
Ein gemeinsamer Unterschied ist:
quelle
Zusamenfassend:
@Spy
und@Mock
werden häufig beim Testen von Code verwendet, aber Entwickler verwirren in Fällen, in denen sie einen von ihnen verwenden müssen, und daher verwenden Entwickler letztendlich@Mock
, um sicher zu sein.@Mock
Sie diese Option, wenn Sie die Funktionalität nur extern testen möchten ohne diese Methode tatsächlich aufzurufen.@Spy
Sie diese Option, wenn Sie die Funktionalität extern + intern mit der aufgerufenen Methode testen möchten .Unten ist das Beispiel, in dem ich das Szenario von Election20xx in Amerika aufgenommen habe.
Die Wähler können nach
VotersOfBelow21
und unterteilt werdenVotersOfABove21
.Die ideale Exit - Umfrage sagt , dass Trump die Wahl gewinnen wird , da
VotersOfBelow21
undVotersOfABove21
beide stimmen für Trumpf sagen : „ Wir gewählte Präsident Trump “Dies ist jedoch nicht das eigentliche Szenario:
Wie testest du es?
Beachten Sie nun, dass in den ersten beiden Klassen beide Altersgruppen sagen, dass sie keine bessere Wahl haben als Trump. Was ausdrücklich bedeutet, dass sie für Trump gestimmt haben, nur weil sie keine Wahl hatten.
Jetzt
ElectionOfYear20XX
sagt der , dass Trump gewonnen hat, weil beide Altersgruppen ihn mit überwältigender Mehrheit gewählt haben.Wenn wir das testen würden
ElectionOfYear20XX
mit @Mock testen würden, könnten wir möglicherweise nicht den wahren Grund herausfinden, warum Trump gewonnen hat. Wir werden nur den externen Grund testen.Wenn wir das
ElectionOfYear20XX
mit @Spy testen, erhalten wir den wahren Grund, warum Trump mit den Ergebnissen der externen Exit-Umfrage gewonnen hat, dh intern + extern.Unsere
ELectionOfYear20XX_Test
Klasse:Dies sollte nur die logischen Testergebnisse ausgeben, dh externe Prüfung:
Testen sowohl
@Spy
extern als auch intern mit tatsächlichem Methodenaufruf.Ausgabe:
quelle