Was sind die Unterschiede zwischen Mocks und Stubs bei Rhino Mocks?


149

Ich habe nicht genug damit gespielt und benutze normalerweise Mocks, aber ich frage mich, was die Unterschiede zwischen diesen beiden sind und wann ich den einen oder anderen bei Rhino Mocks verwenden soll.

Aktualisieren:

Die Antwort auf meine Frage fand ich auch in Ayendes Worten :

Der Unterschied zwischen Stubs und Mocks

Die tatsächliche Definition dieser Begriffe finden Sie in diesem Artikel: Mocks sind keine Stubs . Ich möchte mich auf den Unterschied aus der Sicht von Rhino Mocks konzentrieren.

Ein Mock ist ein Objekt, an das wir Erwartungen setzen können und das überprüft, ob die erwarteten Aktionen tatsächlich stattgefunden haben. Ein Stub ist ein Objekt, das Sie verwenden, um an den zu testenden Code zu übergeben. Sie können Erwartungen daran festlegen, damit es auf bestimmte Weise funktioniert, aber diese Erwartungen werden niemals überprüft. Die Eigenschaften eines Stubs verhalten sich automatisch wie normale Eigenschaften, und Sie können keine Erwartungen an sie setzen.

Wenn Sie das Verhalten des zu testenden Codes überprüfen möchten, verwenden Sie ein Modell mit der entsprechenden Erwartung und überprüfen dies. Wenn Sie nur einen Wert übergeben möchten, der möglicherweise auf eine bestimmte Weise funktionieren muss, aber nicht im Mittelpunkt dieses Tests steht, verwenden Sie einen Stub.

WICHTIG: Ein Stub führt niemals dazu, dass ein Test fehlschlägt.


Antworten:


148

Wie aus diesem Grund

... Einfach ausgedrückt gibt es einen Unterschied zwischen Mock- und Stub-Objekten, und RhinoMocks erkennt, dass wir Tests schreiben können, die ihren Zweck besser angeben.

Scheinobjekte werden verwendet, um Erwartungen zu definieren, dh: In diesem Szenario erwarte ich, dass Methode A () mit solchen und solchen Parametern aufgerufen wird. Verspottungen erfassen und verifizieren solche Erwartungen.

Stubs hingegen haben einen anderen Zweck: Sie erfassen oder verifizieren keine Erwartungen, sondern ermöglichen es uns, das Verhalten und den Zustand des „gefälschten“ Objekts zu „ersetzen“, um ein Testszenario zu verwenden ...


Ich habe einen weiteren nützlichen Beitrag gefunden, der dieselbe Nachricht wie die akzeptierte Antwort auf diese Frage wiedergibt - martinfowler.com/articles/mocksArentStubs.html .
singh1469

20

Im Allgemeinen rufen Unit-Tests Funktionen und Methoden auf und prüfen dann, ob das erwartete Verhalten stattgefunden hat. Diese Funktionen und Methoden erfordern möglicherweise Parameter. Wir verwenden Stubs und Mocks, um diese Parameter zu erfüllen. Manchmal verspotten wir auch globale Objekte.

Stubs

Ein Stub ist ein winziges gefälschtes Objekt, das Ihr Test als Parameter verwenden kann, damit der Funktionsaufruf funktioniert. Auf diese Weise können wir das Verhalten der zu testenden Funktion überprüfen. Wir können keine Nebenwirkungen überprüfen, da der Stub keine Implementierung hat.

Verspottet

Ein Mock ist ein Stub mit einer Implementierung. Wenn unsere zu testende Funktion mit unserem Scheinobjekt interagiert, können wir überprüfen, ob mit dem Modell wie erwartet interagiert wurde.

Angenommen, wir hatten ein nachgebildetes Benutzerobjekt und wollten überprüfen, ob unsere session.login-Methode funktioniert. Möglicherweise möchten wir überprüfen, ob user.lastLoggedIn festgelegt wurde. Wir könnten einen Scheinbenutzer erstellen, der diese Methode implementiert. Wenn wir session.login aufrufen, können wir bestätigen, dass user.lastLoggedIn den erwarteten Status hat.

Um zusammenzufassen

Ein Mock ist ein Stub mit einer Implementierung, mit der wir Nebenwirkungen testen können.

Ist dieser Unterschied noch wichtig?

Ähnlich wie der Unterschied zwischen Gleichnissen und Metaphern ist der Unterschied zwischen Stubs und Mocks subtil und historisch und hat möglicherweise mehr mit den verschiedenen Gemeinschaften und Philosophien in der Testwelt zu tun als mit irgendeinem größeren technischen Unterschied.

Sie repräsentieren leicht unterschiedliche Testansätze. Ein Mock kann wie ein Stub geschrieben werden. Ein Stub kann normalerweise zu einem Mock erweitert werden.

Welches solltest du verwenden?

Möglicherweise stellen Sie fest, dass Sie mit dem Erstellen von Stubs beginnen. Später müssen Sie möglicherweise vollständige Mocks für einige Ihrer Objekte erstellen. Vielleicht möchten Sie alles verspotten, während Sie gehen, oder Sie möchten einfach nur verspotten, wo es erforderlich ist.


7

Unterschied zwischen Mock und Stub: Mit Stub korrigieren Sie die Eingabe Ihres Unit-Tests: Ihr Unit-Test macht also keine Aussage über Stub und Stub, indem Sie die Implementierung einer Methode neu schreiben, um das Verhalten von gefälschten Objekten zu korrigieren. Mit Mock korrigieren Sie die Ausgabe Ihres Unit-Tests: Ihr Unit-Test stellt also eine Erwartung an Ihr Mocking-Objekt, indem Sie die interne Interaktion in Ihrem Mock-Objekt überprüfen.


Sie scheinen zu sagen, dass Ihr Test die Ausgabe eines Mocks "überprüfen" sollte. Wenn Sie das sagen, sind Sie falsch. Ein Mock soll nicht getestet werden; Es ist da, damit Sie anderen Code testen können . Oder bedeutet dein letzter Satz etwas anderes?
Andrew Barber

1
Hallo Andrew, wie ich mit Mock geschrieben habe, korrigierst du die Ausgabe deines Tests, damit du sie nicht testest. Andernfalls habe ich geschrieben, dass Mock es dir ermöglicht, die Interaktion zu überprüfen (Erwartungsverhalten ... ;-)
Hassan Boutougha

1
OK, das macht mehr Sinn. Danke für die Klarstellung!
Andrew Barber

> macht keine Behauptung auf Stub Warum gibt es in vielen Assertionsbibliotheken immer noch Methoden should have been called with, um stubParameter zu bestätigen?
Hellboy

5

Im Falle des Moq-Frameworks ist die Setup-Methode STUB, wobei die Verify-Methode Mock ist


0

Eine Sache, die mir ebenfalls aufgefallen ist, ist, dass ich bei Verwendung von MockRepository.GenerateMock explizit Erwartungen an einen bestimmten Methodenaufruf festlegen muss, um diesen Aufruf abzufangen. Bei Stubs scheint es jede Methode automatisch abzufangen, solange sie virtuell ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.