Was ist der Unterschied zwischen Fälschen, Verspotten und Stubben?

705

Ich weiß, wie ich diese Begriffe verwende, aber ich frage mich, ob es akzeptierte Definitionen für Fälschung , Verspottung und Stubbing für Unit-Tests gibt. Wie definieren Sie diese für Ihre Tests? Beschreiben Sie Situationen, in denen Sie sie möglicherweise verwenden.

So benutze ich sie:

Fake : Eine Klasse, die eine Schnittstelle implementiert, aber feste Daten und keine Logik enthält. Gibt je nach Implementierung einfach "gute" oder "schlechte" Daten zurück.

Mock : Eine Klasse, die eine Schnittstelle implementiert und die Möglichkeit bietet, die Werte für die Rückgabe / Ausnahmen für bestimmte Methoden dynamisch festzulegen und zu überprüfen, ob bestimmte Methoden aufgerufen / nicht aufgerufen wurden.

Stub : Wie eine Scheinklasse, nur dass sie nicht die Möglichkeit bietet, zu überprüfen, ob Methoden aufgerufen / nicht aufgerufen wurden.

Mocks und Stubs können von Hand oder durch ein Mocking-Framework generiert werden. Gefälschte Klassen werden von Hand generiert. Ich benutze Mocks hauptsächlich, um Interaktionen zwischen meiner Klasse und abhängigen Klassen zu überprüfen. Ich verwende Stubs, sobald ich die Interaktionen überprüft habe und alternative Pfade durch meinen Code teste. Ich verwende gefälschte Klassen hauptsächlich, um Datenabhängigkeiten zu abstrahieren oder wenn Mocks / Stubs zu langwierig sind, um sie jedes Mal einzurichten.

Tvanfosson
quelle
6
Nun, Sie haben im Grunde alles in Ihrer "Frage" gesagt :) Ich denke, das sind ziemlich gut akzeptierte Definitionen dieser Begriffe
Eran Galperin
2
Die Wikipedia-Definition von Fake unterscheidet sich davon und behauptet, dass ein Fake "als einfachere Implementierung verwendet wird, z. B. die Verwendung einer In-Memory-Datenbank in den Tests anstelle eines echten Datenbankzugriffs)" Siehe en.wikipedia.org/wiki/Test_double
zumalifeguard
2
Ich habe viel aus der folgenden Ressource gelernt, mit einer ausgezeichneten Erklärung von Robert C. Martin (Onkel Bob): Der kleine Spötter im Clean Code Blog . Es erklärt die Unterschiede und Feinheiten von Dummies, Test-Doubles, Stubs, Spionen, (wahren) Mocks und Fakes. Es erwähnt auch Martin Fowler und erklärt ein wenig die Geschichte der Softwaretests.
Erik
testing.googleblog.com/2013/07/… (eine kurze einseitige Zusammenfassung).
ShreevatsaR
Hier ist meine
Einstellung,

Antworten:

548

Sie können einige Informationen erhalten:

Von Martin Fowler über Mock and Stub

Gefälschte Objekte haben tatsächlich funktionierende Implementierungen, verwenden jedoch normalerweise eine Verknüpfung, wodurch sie nicht für die Produktion geeignet sind

Stubs bieten vordefinierte Antworten auf Anrufe, die während des Tests getätigt wurden, und reagieren normalerweise überhaupt nicht auf etwas außerhalb der für den Test programmierten. Stubs können auch Informationen über Anrufe aufzeichnen, z. B. einen E-Mail-Gateway-Stub, der sich an die Nachrichten erinnert, die er "gesendet" hat, oder nur an die Anzahl der Nachrichten, die er "gesendet" hat.

Mocks sind das, worüber wir hier sprechen: Objekte, die mit Erwartungen vorprogrammiert sind und eine Spezifikation der Anrufe bilden, die sie voraussichtlich erhalten.

Aus xunitpattern :

Fake : Wir erwerben oder erstellen eine sehr einfache Implementierung derselben Funktionalität, die von einer Komponente bereitgestellt wird, von der das SUT abhängt, und weisen das SUT an, sie anstelle der realen zu verwenden.

Stub : Diese Implementierung ist so konfiguriert, dass sie auf Aufrufe vom SUT mit den Werten (oder Ausnahmen) reagiert, die den nicht getesteten Code (siehe Produktionsfehler auf Seite X) innerhalb des SUT ausführen. Eine wichtige Anzeige für die Verwendung eines Teststubs ist der nicht getestete Code, der durch die Unfähigkeit verursacht wird, die indirekten Eingaben des SUT zu steuern

Mock-Objekt , das dieselbe Schnittstelle implementiert wie ein Objekt, von dem das SUT (System Under Test) abhängt. Wir können ein Mock-Objekt als Beobachtungspunkt verwenden, wenn wir eine Verhaltensüberprüfung durchführen müssen, um zu vermeiden, dass eine nicht getestete Anforderung (siehe Produktionsfehler auf Seite X) auftritt, die durch die Unfähigkeit verursacht wird, Nebenwirkungen des Aufrufens von Methoden auf dem SUT zu beobachten.

Persönlich

Ich versuche zu vereinfachen, indem ich: Mock and Stub benutze. Ich verwende Mock, wenn es sich um ein Objekt handelt, das einen Wert zurückgibt, der auf die getestete Klasse festgelegt ist. Ich verwende Stub, um eine zu testende Interface- oder Abstract-Klasse nachzuahmen. Tatsächlich spielt es keine Rolle, wie Sie es nennen, es sind alles Klassen, die nicht in der Produktion verwendet werden und als Dienstprogrammklassen zum Testen verwendet werden.

Patrick Desjardins
quelle
9
Es scheint mir, dass die Definitionen für Stub und Fake im xUnitPattern-Zitat im Vergleich zu Martin Fowlers Zitat umgekehrt sind. Auch dass Martin Fowlers Definitionen von Stub und Fake im Vergleich zu den Definitionen in Tvanfossons ursprünglicher Frage umgekehrt sind. Gibt es in Wirklichkeit allgemein akzeptierte Definitionen dieser beiden Begriffe oder hängt es nur davon ab, mit wem Sie sprechen?
Simon Tewsi
3
+1 für "Ich versuche zu vereinfachen mit: Mock and Stub". Das ist eine tolle Idee!
Brad Cupit
4
Ich kann nicht sehen, wie großartig es ist, nur Mock und Stub zu verwenden. Jedes Testdoppel hat seinen Zweck und damit seine Verwendung.
Hector Ordonez
1
Ich kann den Unterschied zwischen Fake und Mock in der Definition von MF nicht erkennen.
IdontCareAboutReputationPoints
2
@MusuNaji: In der Definition von MF gibt es keine "Erwartungen" in Bezug auf die Konversation für eine Fälschung, außer dass es eine Implementierung für die Schnittstelle gibt. Auf der anderen Seite wird der Mock herausgefordert (wurde diese Methode genannt?).
Dbalakirev
205

Stub - ein Objekt, das vordefinierte Antworten auf Methodenaufrufe liefert.

Mock - ein Objekt, an das Sie Erwartungen setzen.

Fake - ein Objekt mit eingeschränkten Funktionen (zu Testzwecken), z. B. ein gefälschter Webdienst.

Test Double ist der allgemeine Begriff für Stubs, Mocks und Fakes. Aber informell hört man oft Leute, die sie einfach Spott nennen.

Mike
quelle
4
Könnte mir jemand erklären und definieren, was in diesem Zusammenhang eine "eingemachte Antwort" ist?
MasterMastic
14
Ein expliziter Wert anstelle eines berechneten Werts.
Mike
Schließlich! Einige Definitionen kann ich verstehen! Basierend auf diesen Definitionen können mit googletest (gtest) / googlemock (gmock) verspottete Objekte auch Stubs sein, da Sie mit EXPECT_CALL()einer verspotteten Methode s erstellen können, die bestimmte Ausgaben basierend auf bestimmten Eingaben erzwingen, indem Sie den Typ .WillOnce(Invoke(my_func_or_lambda_func))(oder mit .WillRepeatedly()) verwenden Syntax an eine EXPECT_CALL(). Einige Beispiele für die Verwendung Invoke()finden Sie in einem anderen Kontext am Ende meiner langen Antwort hier: stackoverflow.com/a/60905880/4561887 .
Gabriel Staples
Die Dokumentation zu Gmock finden Sie Invoke()hier: github.com/google/googletest/blob/master/googlemock/docs/… . Wie auch immer, die Schlussfolgerung lautet: Mit Google Mock (gmock) können auf einfache Weise sowohl Mocks als auch Stubs erstellt werden , obwohl die meisten Mocks keine Stubs sind.
Gabriel Staples
Mocks sind eine Obermenge von Stubs. Sie können immer noch vordefinierte Antworten zurückgeben, aber dem Entwickler auch ermöglichen, Erwartungen zu setzen. IMO bestimmte Bibliotheken da draußen verwischen die Linien aller Test-Dummies.
Luke
94

Ich bin überrascht, dass es diese Frage schon so lange gibt und noch niemand eine Antwort auf Roy Osheroves "The Art of Unit Testing" gegeben hat .

In "3.1 Einführung von Stubs" wird ein Stub wie folgt definiert:

Ein Stub ist ein steuerbarer Ersatz für eine vorhandene Abhängigkeit (oder einen Mitarbeiter) im System. Mithilfe eines Stubs können Sie Ihren Code testen, ohne sich direkt mit der Abhängigkeit zu befassen.

Und definiert den Unterschied zwischen Stubs und Mocks als:

Die wichtigste Sache, an die Sie sich bei Mocks versus Stubs erinnern sollten, ist, dass Mocks genau wie Stubs sind, aber Sie behaupten gegen das Scheinobjekt, während Sie nicht gegen einen Stub behaupten.

Fake ist nur der Name, der sowohl für Stubs als auch für Mocks verwendet wird. Zum Beispiel, wenn Sie sich nicht für die Unterscheidung zwischen Stubs und Mocks interessieren.

Die Art und Weise, wie Osherove zwischen Stubs und Mocks unterscheidet, bedeutet, dass jede Klasse, die als Fälschung zum Testen verwendet wird, sowohl ein Stub als auch ein Mock sein kann. Was es für einen bestimmten Test ist, hängt ganz davon ab, wie Sie die Schecks in Ihren Test schreiben.

  • Wenn Ihr Test Werte in der zu testenden Klasse oder tatsächlich irgendwo anders als die Fälschung überprüft, wurde die Fälschung als Stub verwendet. Es wurden lediglich Werte für die zu testende Klasse bereitgestellt, entweder direkt durch Werte, die durch Aufrufe zurückgegeben wurden, oder indirekt durch Verursachen von Nebenwirkungen (in einigen Zuständen) infolge von Aufrufen.
  • Wenn Ihr Test die Werte der Fälschung überprüft, wurde sie als Schein verwendet.

Beispiel eines Tests, bei dem die Klasse FakeX als Stub verwendet wird:

const pleaseReturn5 = 5;
var fake = new FakeX(pleaseReturn5);
var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, cut.SomeProperty);

Die fakeInstanz wird als Stub verwendet, da sie Assertüberhaupt nicht verwendet wird fake.

Beispiel eines Tests, bei dem die Testklasse X als Schein verwendet wird:

const pleaseReturn5 = 5;
var fake = new FakeX(pleaseReturn5);
var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, fake.SomeProperty);

In diesem Fall Assertüberprüft das einen Wert auf fake, wodurch diese Fälschung zu einem Schein wird.

Natürlich sind diese Beispiele sehr erfunden, aber ich sehe großen Wert in dieser Unterscheidung. Es macht Sie darauf aufmerksam, wie Sie Ihre Daten testen und wo die Abhängigkeiten Ihres Tests liegen.

Ich stimme dem von Osherove zu

Aus einer rein wartbaren Perspektive verursacht die Verwendung von Mocks in meinen Tests mehr Probleme als die Nichtverwendung. Das war meine Erfahrung, aber ich lerne immer etwas Neues.

Die Behauptung gegen die Fälschung ist etwas, das Sie wirklich vermeiden möchten, da Ihre Tests in hohem Maße von der Implementierung einer Klasse abhängen, die überhaupt nicht getestet wird. Dies bedeutet, dass die Tests für die Klasse ActualClassUnderTestunterbrochen werden können, da sich die Implementierung für ClassUsedAsMockgeändert hat. Und das riecht übel nach mir. Tests für ActualClassUnderTestsollten vorzugsweise nur dann unterbrochen werden, wenn sie ActualClassUnderTestgeändert werden.

Mir ist klar, dass das Schreiben von Behauptungen gegen die Fälschung eine gängige Praxis ist, insbesondere wenn Sie ein spöttischer TDD-Abonnent sind. Ich glaube, ich bin fest mit Martin Fowler im Lager der Klassiker verbunden (siehe Martin Fowlers "Mocks are not Stubs" ) und vermeide wie Osherove Interaktionstests (die nur durch Behauptung gegen die Fälschung durchgeführt werden können) so weit wie möglich.

Zum Spaß beim Lesen, warum Sie Verspottungen wie hier definiert vermeiden sollten, googeln Sie nach "Fowler Mockist Classicist". Sie finden eine Vielzahl von Meinungen.

Marjan Venema
quelle
30

Wie in der Antwort mit den meisten Stimmen erwähnt, erörtert Martin Fowler diese Unterscheidungen in Mocks Aren't Stubs und insbesondere in der Unterüberschrift Der Unterschied zwischen Mocks und Stubs. Lesen Sie daher unbedingt diesen Artikel.

Anstatt sich darauf zu konzentrieren, wie sich diese Dinge unterscheiden, finde ich es aufschlussreicher, sich darauf zu konzentrieren, warum dies unterschiedliche Konzepte sind. Jedes existiert für einen anderen Zweck.

Fälschungen

Eine Fälschung ist eine Implementierung, die sich "natürlich" verhält, aber nicht "echt" ist. Dies sind unscharfe Konzepte, und so haben verschiedene Menschen unterschiedliche Vorstellungen davon, was Dinge zu einer Fälschung macht.

Ein Beispiel für eine Fälschung ist eine speicherinterne Datenbank (z. B. die Verwendung von SQLite mit dem :memory:Speicher). Sie würden dies niemals für die Produktion verwenden (da die Daten nicht beibehalten werden), aber es ist als Datenbank für die Verwendung in einer Testumgebung vollkommen ausreichend. Es ist auch viel leichter als eine "echte" Datenbank.

Als weiteres Beispiel verwenden Sie möglicherweise eine Art Objektspeicher (z. B. Amazon S3) in der Produktion, aber in einem Test können Sie Objekte einfach in Dateien auf der Festplatte speichern. dann wäre Ihre Implementierung "Auf Festplatte speichern" eine Fälschung. (Oder Sie können sogar den Vorgang "Auf Festplatte speichern" vortäuschen, indem Sie stattdessen ein In-Memory-Dateisystem verwenden.)

Stellen Sie sich als drittes Beispiel ein Objekt vor, das eine Cache-API bereitstellt. Ein Objekt, das die richtige Schnittstelle implementiert, aber einfach überhaupt kein Caching durchführt, sondern immer einen Cache-Fehler zurückgibt, wäre eine Art Fälschung.

Der Zweck einer Fälschung besteht nicht darin, das Verhalten des zu testenden Systems zu beeinflussen , sondern die Implementierung des Tests zu vereinfachen (indem unnötige oder schwergewichtige Abhängigkeiten beseitigt werden).

Stubs

Ein Stub ist eine Implementierung, die sich "unnatürlich" verhält. Es ist vorkonfiguriert (normalerweise vom Testaufbau), um auf bestimmte Eingaben mit bestimmten Ausgaben zu reagieren.

Der Zweck eines Stubs besteht darin, Ihr zu testendes System in einen bestimmten Zustand zu versetzen. Zum Beispiel, wenn Sie einen Test für einige Code schreiben , dass wirkt mit einer REST - API, könnten Sie Stub die REST - API mit einer API , dass immer eine Dosen-Antwort zurückgibt, oder dass reagiert auf eine API - Anforderung mit einem bestimmten Fehler. Auf diese Weise können Sie Tests schreiben, die Aussagen darüber machen, wie das System auf diese Zustände reagiert. Testen Sie beispielsweise die Antwort, die Ihre Benutzer erhalten, wenn die API einen 404-Fehler zurückgibt.

Ein Stub wird normalerweise implementiert, um nur auf die genauen Interaktionen zu reagieren, auf die Sie ihn angewiesen haben. Aber das Hauptmerkmal, das etwas zu einem Stub macht, ist sein Zweck : Bei einem Stub geht es darum, Ihren Testfall einzurichten.

Verspottet

Ein Mock ähnelt einem Stub, es wurde jedoch eine Überprüfung hinzugefügt. Der Zweck eines Mocks besteht darin, Aussagen darüber zu treffen, wie Ihr zu testendes System mit der Abhängigkeit interagiert .

Zum Beispiel, wenn Sie einen Test für ein System , dass Uploads von Dateien auf eine Website schreiben, könnten Sie einen bauen Mock , der eine Datei akzeptiert und dass Sie behaupten können , dass die hochgeladene Datei korrekt war. In kleinerem Maßstab wird häufig ein Mock eines Objekts verwendet, um zu überprüfen, ob das zu testende System bestimmte Methoden des verspotteten Objekts aufruft.

Mocks sind an Interaktionstests gebunden , bei denen es sich um eine spezifische Testmethode handelt. Menschen, die lieber den Systemstatus als die Systeminteraktionen testen möchten, werden Mocks, wenn überhaupt, sparsam einsetzen.

Test verdoppelt sich

Fälschungen, Stubs und Mocks gehören zur Kategorie der Testdoppel . Ein Testdouble ist ein Objekt oder System, das Sie in einem Test anstelle von etwas anderem verwenden. Bei den meisten automatisierten Softwaretests werden Testdoppel der einen oder anderen Art verwendet. Einige andere Arten von Test-Doubles umfassen Dummy-Werte , Spione und E / A- Blackholes .

Daniel Pryden
quelle
11

Um die Verwendung von Stubs und Mocks zu veranschaulichen, möchte ich auch ein Beispiel hinzufügen, das auf Roy Osheroves " The Art of Unit Testing " basiert .

Stellen Sie sich vor, wir haben eine LogAnalyzer-Anwendung, die die einzige Funktionalität zum Drucken von Protokollen bietet. Es muss nicht nur mit einem Webdienst kommunizieren, sondern wenn der Webdienst einen Fehler auslöst, muss LogAnalyzer den Fehler in einer anderen externen Abhängigkeit protokollieren und per E-Mail an den Webdienstadministrator senden.

Hier ist die Logik, die wir in LogAnalyzer testen möchten:

if(fileName.Length<8)
{
 try
  {
    service.LogError("Filename too short:" + fileName);
  }
 catch (Exception e)
  {
    email.SendEmail("a","subject",e.Message);
  }
}

Wie testen Sie, ob LogAnalyzer den E-Mail-Dienst korrekt aufruft, wenn der Webdienst eine Ausnahme auslöst? Hier sind die Fragen, mit denen wir konfrontiert sind:

  • Wie können wir den Webdienst ersetzen?

  • Wie können wir eine Ausnahme vom Webdienst simulieren, um den Anruf beim E-Mail-Dienst zu testen?

  • Woher wissen wir, dass der E-Mail-Dienst korrekt oder überhaupt aufgerufen wurde?

Wir können die ersten beiden Fragen beantworten, indem wir einen Stub für den Webdienst verwenden . Um das dritte Problem zu lösen, können wir ein Scheinobjekt für den E-Mail-Dienst verwenden .

Eine Fälschung ist ein Oberbegriff, der verwendet werden kann, um entweder einen Stub oder einen Mock zu beschreiben. In unserem Test haben wir zwei Fälschungen. Eine davon ist der E-Mail-Dienst-Mock, mit dem wir überprüfen, ob die richtigen Parameter an den E-Mail-Dienst gesendet wurden. Der andere ist ein Stub, mit dem wir eine vom Webdienst ausgelöste Ausnahme simulieren. Es ist ein Stub, weil wir den gefälschten Webdienst nicht verwenden, um das Testergebnis zu überprüfen, sondern nur um sicherzustellen, dass der Test korrekt ausgeführt wird. Der E-Mail-Dienst ist ein Schein, weil wir dagegen behaupten werden, dass er korrekt aufgerufen wurde.

[TestFixture]
public class LogAnalyzer2Tests
{
[Test]
 public void Analyze_WebServiceThrows_SendsEmail()
 {
   StubService stubService = new StubService();
   stubService.ToThrow= new Exception("fake exception");
   MockEmailService mockEmail = new MockEmailService();

   LogAnalyzer2 log = new LogAnalyzer2();
   log.Service = stubService
   log.Email=mockEmail;
   string tooShortFileName="abc.ext";
   log.Analyze(tooShortFileName);

   Assert.AreEqual("a",mockEmail.To); //MOCKING USED
   Assert.AreEqual("fake exception",mockEmail.Body); //MOCKING USED
   Assert.AreEqual("subject",mockEmail.Subject);
 }
}
Nanospeck
quelle
9

Das, was Sie darauf behaupten, wird als Scheinobjekt bezeichnet , und alles andere, was gerade zum Testlauf beigetragen hat, ist ein Stub .

Arezoo Bagherzadi
quelle
1
während andere Antworten sehr detailliert sind und wirklich gut sind. Dieser macht es so klar und einfach, den Unterschied zu machen, dass es schwer ist, nicht zu stimmen. gj!
Mario Garcia
6

Es geht darum, die Tests ausdrucksstark zu machen. Ich setze Erwartungen an einen Mock, wenn der Test eine Beziehung zwischen zwei Objekten beschreiben soll. Ich stoppe Rückgabewerte, wenn ich ein unterstützendes Objekt einrichte, um zu dem interessanten Verhalten im Test zu gelangen.

Steve Freeman
quelle
6

Wenn Sie mit Arrange-Act-Assert vertraut sind, besteht eine Möglichkeit, den für Sie nützlichen Unterschied zwischen Stub und Mock zu erklären, darin, dass Stubs zum Arrangierabschnitt gehören, da sie zum Anordnen des Eingabestatus dienen und Mocks dazu gehören den Assert-Abschnitt, wie er zum Durchsetzen von Ergebnissen dient.

Dummies machen nichts. Sie dienen nur zum Ausfüllen von Parameterlisten, damit Sie keine undefinierten oder Null-Fehler erhalten. Sie sind auch vorhanden, um die Typprüfung in streng typisierten Sprachen zu erfüllen, sodass Sie kompilieren und ausführen können.

Sammi
quelle
3

Stub, Fakes und Mocks haben unterschiedliche Bedeutungen in verschiedenen Quellen. Ich empfehle Ihnen, die internen Begriffe Ihres Teams vorzustellen und deren Bedeutung zu vereinbaren.

Ich denke, es ist wichtig, zwischen zwei Ansätzen zu unterscheiden: - Verhaltensvalidierung (impliziert Verhaltenssubstitution) - Endzustandsvalidierung (impliziert Verhaltensemulation)

Im Fehlerfall sollten Sie eine E-Mail senden. Bei der Verhaltensüberprüfung überprüfen Sie, ob die Methode Sendvon IEmailSendereinmal ausgeführt wurde. Und Sie müssen das Rückgabeergebnis dieser Methode emulieren und die ID der gesendeten Nachricht zurückgeben. Sie sagen also: "Ich gehe davon aus, dass Senddies aufgerufen wird. Und ich werde für jeden Anruf nur eine Dummy-ID (oder eine zufällige ID) zurückgeben . " Dies ist eine Verhaltensüberprüfung: emailSender.Expect(es=>es.Send(anyThing)).Return((subject,body) => "dummyId")

Wenn Sie eine Statusüberprüfung durchführen, müssen Sie TestEmailSenderdiese Implementierungen erstellen IEmailSender. Und implementieren Sie die SendMethode - indem Sie Eingaben in einer Datenstruktur speichern, die für die zukünftige Statusüberprüfung verwendet wird, z. B. ein Array einiger Objekte, SentEmailsund dann testen, ob Sie die SentEmailserwartete E-Mail enthalten. Dies ist eine Zustandsüberprüfung: Assert.AreEqual(1, emailSender.SentEmails.Count)

Aus meinen Lesungen ging hervor, dass die Verhaltensvalidierung normalerweise als Mocks bezeichnet wird . Und die Zustandsvalidierung wird normalerweise als Stubs oder Fakes bezeichnet .

Marat Gallyamov
quelle
Wirklich gut detaillierte und klare Definition.
Shyam Sundar Singh Tomar
2

Stub und Fake sind Objekte, da sie ihre Reaktion basierend auf Eingabeparametern variieren können. Der Hauptunterschied zwischen ihnen besteht darin, dass ein Fake einer realen Implementierung näher kommt als ein Stub. Stubs enthalten grundsätzlich fest codierte Antworten auf eine erwartete Anfrage. Sehen wir uns ein Beispiel an:

public class MyUnitTest {

 @Test
 public void testConcatenate() {
  StubDependency stubDependency = new StubDependency();
  int result = stubDependency.toNumber("one", "two");
  assertEquals("onetwo", result);
 }
}

public class StubDependency() {
 public int toNumber(string param) {
  if (param == “one”) {
   return 1;
  }
  if (param == “two”) {
   return 2;
  }
 }
}

Ein Mock ist ein Schritt nach oben von Fälschungen und Stubs. Mocks bieten die gleiche Funktionalität wie Stubs, sind jedoch komplexer. Für sie können Regeln definiert werden, die festlegen, in welcher Reihenfolge Methoden in ihrer API aufgerufen werden müssen. Die meisten Mocks können nachverfolgen, wie oft eine Methode aufgerufen wurde, und anhand dieser Informationen reagieren. Mocks kennen im Allgemeinen den Kontext jedes Anrufs und können in verschiedenen Situationen unterschiedlich reagieren. Aus diesem Grund erfordern Mocks einige Kenntnisse der Klasse, die sie verspotten. Ein Stub kann im Allgemeinen nicht verfolgen, wie oft eine Methode aufgerufen wurde oder in welcher Reihenfolge eine Folge von Methoden aufgerufen wurde. Ein Mock sieht aus wie:

public class MockADependency {

 private int ShouldCallTwice;
 private boolean ShouldCallAtEnd;
 private boolean ShouldCallFirst;

 public int StringToInteger(String s) {
  if (s == "abc") {
   return 1;
  }
  if (s == "xyz") {
   return 2;
  }
  return 0;
 }

 public void ShouldCallFirst() {
  if ((ShouldCallTwice > 0) || ShouldCallAtEnd)
   throw new AssertionException("ShouldCallFirst not first thod called");
  ShouldCallFirst = true;
 }

 public int ShouldCallTwice(string s) {
  if (!ShouldCallFirst)
   throw new AssertionException("ShouldCallTwice called before ShouldCallFirst");
  if (ShouldCallAtEnd)
   throw new AssertionException("ShouldCallTwice called after ShouldCallAtEnd");
  if (ShouldCallTwice >= 2)
   throw new AssertionException("ShouldCallTwice called more than twice");
  ShouldCallTwice++;
  return StringToInteger(s);
 }

 public void ShouldCallAtEnd() {
  if (!ShouldCallFirst)
   throw new AssertionException("ShouldCallAtEnd called before ShouldCallFirst");
  if (ShouldCallTwice != 2) throw new AssertionException("ShouldCallTwice not called twice");
  ShouldCallAtEnd = true;
 }

}
Alireza Rahmani Khalili
quelle
1

fake objectist eine echte Implementierung der Schnittstelle (Protokoll) oder eine Erweiterung unter Verwendung von Vererbung oder anderen Ansätzen, die zum Erstellen verwendet werden können - ist Abhängigkeit. Normalerweise wird es vom Entwickler als einfachste Lösung erstellt, um einige Abhängigkeiten zu ersetzen

stub objectist ein nacktes Objekt (0, nil und Methoden ohne Logik) mit einem zusätzlichen und vordefinierten (vom Entwickler) Status , um zurückgegebene Werte zu definieren. Normalerweise wird es vom Framework erstellt

mock objectist sehr ähnlich, stub objectaber der zusätzliche Status wird während der Programmausführung geändert, um zu überprüfen, ob etwas passiert ist (Methode wurde aufgerufen).

yoAlex5
quelle