Ich habe verschiedene Artikel über Spott und Stubbing beim Testen gelesen, darunter Martin Fowlers Mocks Aren't Stubs , verstehe aber den Unterschied immer noch nicht.
963
Ich habe verschiedene Artikel über Spott und Stubbing beim Testen gelesen, darunter Martin Fowlers Mocks Aren't Stubs , verstehe aber den Unterschied immer noch nicht.
Antworten:
Stub
Ich glaube, der größte Unterschied ist, dass ein Stub, den Sie bereits mit vorbestimmtem Verhalten geschrieben haben. Sie hätten also eine Klasse, die die Abhängigkeit (abstrakte Klasse oder Schnittstelle höchstwahrscheinlich) implementiert, die Sie zu Testzwecken vortäuschen, und die Methoden würden nur mit festgelegten Antworten ausgeblendet. Sie würden nichts Besonderes tun und Sie hätten den gestoppelten Code dafür bereits außerhalb Ihres Tests geschrieben.
Spotten
Ein Mock ist etwas, das Sie im Rahmen Ihres Tests mit Ihren Erwartungen einrichten müssen. Ein Mock wird nicht auf eine vorgegebene Weise eingerichtet, sodass Sie Code haben, der dies in Ihrem Test ausführt. Mocks werden in gewisser Weise zur Laufzeit festgelegt, da der Code, der die Erwartungen festlegt, ausgeführt werden muss, bevor sie etwas tun.
Unterschied zwischen Mocks und Stubs
Mit Mocks geschriebene Tests folgen normalerweise einem
initialize -> set expectations -> exercise -> verify
Testmuster. Während der vorab geschriebene Stub einem folgen würdeinitialize -> exercise -> verify
.Ähnlichkeit zwischen Mocks und Stubs
Der Zweck von beiden besteht darin, das Testen aller Abhängigkeiten einer Klasse oder Funktion zu eliminieren, damit Ihre Tests fokussierter und einfacher in dem sind, was sie zu beweisen versuchen.
quelle
Vorwort
Es gibt verschiedene Definitionen von Objekten, die nicht real sind. Der allgemeine Begriff ist Testdoppel . Dieser Begriff umfasst: Dummy , Fake , Stub , Mock .
Referenz
Nach Martin Fowlers Artikel :
Stil
Mocks vs Stubs = Verhaltenstests vs Zustandstests
Prinzip
Nach dem Prinzip des Tests kann nur eine Sache pro Test mehrere Stubs in einem Test enthalten, aber im Allgemeinen gibt es nur einen Schein.
Lebenszyklus
Testlebenszyklus mit Stubs:
Testlebenszyklus mit Mocks:
Zusammenfassung
Sowohl Mocks- als auch Stubs-Tests geben eine Antwort auf die Frage: Was ist das Ergebnis?
Tests mit Mocks interessieren sich auch für: Wie wurde das Ergebnis erzielt?
quelle
Ein Stub ist ein einfaches falsches Objekt. Es stellt nur sicher, dass der Test reibungslos verläuft.
Ein Mock ist ein schlauerer Stummel. Sie überprüfen, ob Ihr Test erfolgreich ist.
quelle
Hier ist eine Beschreibung von jedem, gefolgt von einem Beispiel aus der realen Welt.
Dummy - nur falsche Werte, um die zu befriedigen
API
.Fake - Erstellen Sie eine Testimplementierung einer Klasse, die möglicherweise von einer externen Infrastruktur abhängig ist. (Es wird empfohlen, dass Ihr Komponententest NICHT mit der externen Infrastruktur interagiert.)
Stub - Override-Methoden zur Rückgabe fest codierter Werte, auch als bezeichnet
state-based
.Mock - sehr ähnlich,
Stub
aberinteraction-based
nicht staatlich. Dies bedeutet, dass Sie nicht erwartenMock
, einen Wert zurückzugeben, sondern davon ausgehen, dass eine bestimmte Reihenfolge der Methodenaufrufe erfolgt.Stubs
undMocks
sind eigentlich Untertypen vonMock
, beide tauschen echte Implementierung mit Testimplementierung aus, aber aus unterschiedlichen, spezifischen Gründen.quelle
Im codeschool.com- Kurs Rails Testing for Zombies geben sie diese Definition der Begriffe an:
Stub
Spotten
Wie Sean Copenhaver in seiner Antwort beschrieben hat, besteht der Unterschied darin, dass Verspottungen Erwartungen setzen (dh Aussagen darüber machen, ob oder wie sie angerufen werden).
quelle
Stubs bestehen Ihre Tests nicht, Mock kann.
quelle
Ich denke, die einfachste und klarere Antwort auf diese Frage gibt Roy Osherove in seinem Buch The art of Unit Testing (Seite 85).
Das heißt, wenn Sie Behauptungen gegen die Fälschung aufstellen, bedeutet dies, dass Sie die Fälschung als Schein verwenden. Wenn Sie die Fälschung nur verwenden, um den Test ohne Behauptung darüber durchzuführen, verwenden Sie die Fälschung als Stub.
quelle
Lassen Sie mich versuchen, alle obigen Erklärungen zusammenzufassen:
quelle
Ein Mock testet nur das Verhalten und stellt sicher, dass bestimmte Methoden aufgerufen werden. Ein Stub ist eine testbare Version (per se) eines bestimmten Objekts.
Was meinst du mit Apple?
quelle
Wenn Sie es mit dem Debuggen vergleichen:
quelle
Die Verwendung eines mentalen Modells hat mir wirklich geholfen, dies zu verstehen, und nicht alle Erklärungen und Artikel, die nicht ganz "eingedrungen" sind.
Stellen Sie sich vor, Ihr Kind hat eine Glasplatte auf dem Tisch und beginnt damit zu spielen. Jetzt hast du Angst, dass es kaputt geht. Also gibst du ihm stattdessen eine Plastikplatte. Das wäre ein Mock (gleiches Verhalten, gleiche Schnittstelle, "weichere" Implementierung).
Angenommen, Sie haben keinen Plastikersatz, und Sie erklären: "Wenn Sie weiter damit spielen, wird es kaputt gehen!". Das ist ein Stub , Sie haben im Voraus einen vordefinierten Status angegeben.
Ein Dummy wäre die Gabel, die er nicht einmal benutzt hat ... und ein Spion könnte so etwas wie die gleiche Erklärung sein, die Sie bereits benutzt haben und die funktioniert hat.
quelle
Ich denke, der wichtigste Unterschied zwischen ihnen sind ihre Absichten.
Lassen Sie mich versuchen, es in WARUM Stummel vs. WARUM Mock zu erklären
Angenommen, ich schreibe Testcode für den öffentlichen Timeline-Controller meines Mac-Twitter-Clients
Hier ist ein Testbeispielcode
Indem Sie Mock schreiben, ermitteln Sie die Beziehung zur Objektzusammenarbeit, indem Sie überprüfen, ob die Erwartungen erfüllt sind, während Stub nur das Verhalten des Objekts simuliert.
Ich schlage vor, diesen Artikel zu lesen, wenn Sie mehr über Mocks erfahren möchten: http://jmock.org/oopsla2004.pdf
quelle
Um ganz klar und praktisch zu sein:
Stub: Eine Klasse oder ein Objekt, das die Methoden der zu fälschenden Klasse / des zu fälschenden Objekts implementiert und immer das zurückgibt, was Sie möchten.
Beispiel in JavaScript:
Mock: Das Gleiche gilt für stub, fügt jedoch eine Logik hinzu, die beim Aufrufen einer Methode "überprüft", sodass Sie sicher sein können, dass eine Implementierung diese Methode aufruft.
Stellen Sie sich als Beispiel vor, dass Sie eine Benutzerregistrierungsklasse testen, wie @mLevan sagt. Nach dem Aufruf von Save sollte SendConfirmationEmail aufgerufen werden.
Ein sehr dummer Code Beispiel:
quelle
Diese Folie erklärt die Hauptunterschiede sehr gut.
* Aus CSE 403 Lecture 16, University of Washington (Folie erstellt von "Marty Stepp")
quelle
Ich mag die Erklärung von Roy Osherove [ Videolink ] .
quelle
quelle
siehe Testdoppel:
Stub : Stub ist ein Objekt, das vordefinierte Daten enthält und diese zum Beantworten von Anrufen während Tests verwendet. Beispiel : Ein Objekt, das einige Daten aus der Datenbank abrufen muss, um auf einen Methodenaufruf zu antworten.
Mocks : Mocks sind Objekte, die empfangene Anrufe registrieren. In der Testzusicherung können wir bei Mocks überprüfen, ob alle erwarteten Aktionen ausgeführt wurden. Zum Beispiel : eine Funktion, die den E-Mail-Versanddienst aufruft. Für mehr überprüfen Sie dies einfach .
quelle
Eine Fälschung ist ein Oberbegriff, der verwendet werden kann, um entweder einen Stub oder ein Scheinobjekt (handgeschrieben oder auf andere Weise) zu beschreiben, da beide wie das reale Objekt aussehen.
Ob eine Fälschung ein Stub oder ein Mock ist, hängt davon ab, wie sie im aktuellen Test verwendet wird. Wenn es verwendet wird, um eine Interaktion zu überprüfen (gegen die behauptet wird), ist es ein Scheinobjekt. Ansonsten ist es ein Stummel.
Fakes sorgt dafür, dass der Test reibungslos verläuft. Dies bedeutet, dass der Leser Ihres zukünftigen Tests versteht, wie sich das gefälschte Objekt verhält, ohne seinen Quellcode lesen zu müssen (ohne von externen Ressourcen abhängig zu sein).
Was bedeutet reibungsloser Testlauf?
Beispiel im folgenden Code:
Sie möchten die mailService.SendEMail () -Methode testen. Dazu müssen Sie eine Ausnahme in Ihrer Testmethode simulieren. Sie müssen also nur eine Fake Stub-errorService-Klasse erstellen, um dieses Ergebnis zu simulieren. Dann kann Ihr Testcode testen mailService.SendEMail () -Methode. Wie Sie sehen, müssen Sie ein Ergebnis simulieren, das aus einer anderen External Dependency ErrorService-Klasse stammt.
quelle
Direkt aus dem Papier Mock Roles, nicht Objects , von den Entwicklern von jMock:
Die Hauptunterschiede sind also:
Um es zusammenzufassen, während auch die Verwirrung zu zerstreuen versucht Fowler Artikel Titel: Mocks sind Stubs, aber sie sind nicht nur Stubs .
quelle
Ich las The Art of Unit Testing und stieß auf die folgende Definition:
quelle
Ich bin auf diesen interessanten Artikel von UncleBob The Little Mocker gestoßen . Es erklärt die gesamte Terminologie auf sehr leicht verständliche Weise und ist daher für Anfänger nützlich. Der Artikel von Martin Fowlers ist besonders für Anfänger wie mich schwer zu lesen.
quelle
Stub hilft uns, den Test durchzuführen. Wie? Es gibt Werte an, die beim Ausführen des Tests helfen. Diese Werte sind selbst nicht real und wir haben diese Werte nur zum Ausführen des Tests erstellt. Zum Beispiel erstellen wir eine HashMap, um uns Werte zu geben, die den Werten in der Datenbanktabelle ähnlich sind. Anstatt direkt mit der Datenbank zu interagieren, interagieren wir mit Hashmap.
Mock ist ein gefälschtes Objekt, das den Test ausführt. wo wir behaupten.
quelle
Siehe das folgende Beispiel für Mocks vs Stubs mit C # und Moq Framework. Moq hat kein spezielles Schlüsselwort für Stub, aber Sie können das Mock-Objekt auch zum Erstellen von Stubs verwenden.
quelle
Sichtweise von Stub- und Mock-Tests:
Stub ist eine Dummy-Implementierung, die vom Benutzer statisch ausgeführt wird, dh wenn Stub den Implementierungscode schreibt. Daher kann die Dienstdefinition und der dynamische Zustand nicht verarbeitet werden. Normalerweise erfolgt dies im JUnit-Framework, ohne das Mocking-Framework zu verwenden.
Mock ist auch eine Dummy-Implementierung, aber die Implementierung erfolgt dynamisch mithilfe von Mocking-Frameworks wie Mockito. So können wir Bedingungs- und Dienstdefinitionen dynamisch behandeln, dh Mocks können zur Laufzeit dynamisch aus Code erstellt werden. Mit Mock können wir Stubs also dynamisch implementieren.
quelle
Plus nützliche Antworten, einer der mächtigsten Punkte bei der Verwendung von Mocks als Subs
Wenn der Mitarbeiter [von dem der Hauptcode abhängt] nicht unter unserer Kontrolle steht (z. B. aus einer Bibliothek eines Drittanbieters),
ist Stub in diesem Fall schwieriger zu schreiben als zu verspotten .
quelle
Ich habe in meiner Antwort Python-Beispiele verwendet, um die Unterschiede zu veranschaulichen.
Stub - Stubbing ist eine Softwareentwicklungstechnik, mit der Klassenmethoden früh im Entwicklungslebenszyklus implementiert werden. Sie werden üblicherweise als Platzhalter für die Implementierung einer bekannten Schnittstelle verwendet, wobei die Schnittstelle finalisiert oder bekannt ist, die Implementierung jedoch noch nicht bekannt oder finalisiert ist. Sie beginnen mit Stubs, was einfach bedeutet, dass Sie nur die Definition einer Funktion aufschreiben und den eigentlichen Code für später belassen. Der Vorteil ist, dass Sie Methoden nicht vergessen und weiterhin über Ihr Design nachdenken können, während Sie es im Code sehen. Sie können Ihren Stub auch eine statische Antwort zurückgeben lassen, damit die Antwort sofort von anderen Teilen Ihres Codes verwendet werden kann. Stub-Objekte liefern eine gültige Antwort, aber sie sind statisch, unabhängig davon, welche Eingabe Sie übergeben. Sie erhalten immer dieselbe Antwort:
Spotten werden in Scheintestfällen verwendet, die bestätigen, dass bestimmte Methoden für diese Objekte aufgerufen werden. Scheinobjekte sind simulierte Objekte, die das Verhalten realer Objekte auf kontrollierte Weise nachahmen. Normalerweise erstellen Sie ein Scheinobjekt, um das Verhalten eines anderen Objekts zu testen. Mit Mocks können wir Ressourcen simulieren, die entweder nicht verfügbar oder für Unit-Tests zu unhandlich sind.
mymodule.py:
test.py:
Dies ist ein sehr einfaches Beispiel, das nur rm ausführt und den Parameter bestätigt, mit dem es aufgerufen wurde. Sie können Mock für Objekte verwenden, nicht nur für die hier gezeigten Funktionen, sondern Sie können auch einen Wert zurückgeben, damit ein Mock-Objekt verwendet werden kann, um einen Stub zum Testen zu ersetzen.
Weitere Informationen zu unittest.mock finden Sie in Python 2.x. Mock ist nicht in unittest enthalten, sondern ein herunterladbares Modul, das über pip heruntergeladen werden kann (pip install mock).
Ich habe auch "The Art of Unit Testing" von Roy Osherove gelesen und ich denke, es wäre großartig, wenn ein ähnliches Buch mit Python- und Python-Beispielen geschrieben würde. Wenn jemand von einem solchen Buch weiß, teilen Sie es bitte. Prost :)
quelle
Ein Stub ist ein gefälschtes Objekt, das zu Testzwecken erstellt wurde. Ein Mock ist ein Stub, der aufzeichnet, ob erwartete Anrufe tatsächlich aufgetreten sind.
quelle
Ein Stub ist eine leere Funktion, mit der unbehandelte Ausnahmen bei Tests vermieden werden:
Ein Mock ist eine künstliche Funktion, mit der Betriebssystem-, Umgebungs- oder Hardwareabhängigkeiten während der Tests vermieden werden:
In Bezug auf Behauptungen und Zustand:
Verweise
quelle
Dort oben gibt es viele gültige Antworten, aber ich denke, es lohnt sich, dieses Formular zu erwähnen: Onkel Bob: https://8thlight.com/blog/uncle-bob/2014/05/14/TheLittleMocker.html
Die beste Erklärung aller Zeiten mit Beispielen!
quelle
Ein Mock ist sowohl ein technisches als auch ein funktionales Objekt.
Der Schein ist technisch . Es wird in der Tat von einer Spottbibliothek erstellt (EasyMock, JMockit und in jüngerer Zeit sind Mockito dafür bekannt), dank der Bytecode-Generierung .
Die Scheinimplementierung wird so generiert , dass wir sie instrumentieren können, um beim Aufrufen einer Methode einen bestimmten Wert zurückzugeben, aber auch einige andere Dinge wie die Überprüfung, ob eine Scheinmethode mit bestimmten Parametern aufgerufen wurde (strenge Prüfung) oder welche Parameter auch immer ( keine strenge Kontrolle).
Ein Mock instanziieren:
Verhalten aufzeichnen:
Aufruf überprüfen:
Dies ist eindeutig nicht die natürliche Methode, um die Foo-Klasse / das Foo-Verhalten zu instanziieren / zu überschreiben. Deshalb beziehe ich mich auf einen technischen Aspekt.
Aber das Mock ist auch funktional , weil es eine Instanz der Klasse ist , müssen wir von der SUT zu isolieren. Und mit aufgezeichneten Verhaltensweisen könnten wir es im SUT genauso verwenden wie mit einem Stub.
Der Stub ist nur ein funktionales Objekt: Das ist eine Instanz der Klasse, die wir vom SUT isolieren müssen, und das ist alles. Das bedeutet, dass sowohl die Stub-Klasse als auch alle Verhaltens-Fixtures, die während unserer Unit-Tests benötigt werden, explizit definiert werden müssen.
Zum Beispiel
hello()
müsste ein Stub dieFoo
Klasse in eine Unterklasse unterteilen (oder ihre Schnittstelle implementieren, über die sie verfügt) und Folgendes überschreibenhello()
:Wenn für ein anderes Testszenario eine andere Wertrückgabe erforderlich ist, müssen wir wahrscheinlich eine generische Methode zum Festlegen der Rückgabe definieren:
Anderes Szenario: Wenn ich eine Nebenwirkungsmethode hätte (keine Rückgabe) und überprüfen würde, ob diese Methode aufgerufen wurde, hätte ich wahrscheinlich einen Booleschen Wert oder einen Zähler in die Stub-Klasse einfügen müssen, um zu zählen, wie oft die Methode aufgerufen wurde.
Fazit
Der Stub benötigt oft viel Overhead / Code, um für Ihren Unit-Test zu schreiben. Was Mock verhindert, dank der sofort einsatzbereiten Aufnahme- / Überprüfungsfunktionen.
Aus diesem Grund wird der Stub-Ansatz heutzutage in der Praxis mit dem Aufkommen hervorragender Scheinbibliotheken selten verwendet.
Über den Artikel von Martin Fowler: Ich denke nicht, dass ich ein "Mockist" -Programmierer bin, während ich Mocks benutze und Stubs vermeide.
Aber ich verwende Mock, wenn es wirklich erforderlich ist (ärgerliche Abhängigkeiten), und ich bevorzuge Test-Slicing- und Mini-Integrationstests, wenn ich eine Klasse mit Abhängigkeiten teste, deren Mocking ein Overhead wäre.
quelle