Frage

Ich weiß, wie ich diese Begriffe verwenden, aber ich frage mich, ob es akzeptiert werden Definitionen für Fälschen , spöttischen und Anstoßen für Unit-Tests? Wie definieren Sie diese für Ihre Tests? Beschreiben Sie Situationen, in denen Sie können jeder verwenden.

Hier ist, wie ich sie:

Gefälschte : eine Klasse, die eine Schnittstelle implementiert, aber feste Daten und keine Logik enthält. „Gut“ oder „schlecht“ Daten in Abhängigkeit von der Implementierung einfach zurück.

Mock : eine Klasse, die eine Schnittstelle implementiert und ermöglicht die Fähigkeit, dynamisch die Werte zurück / Ausnahmen von bestimmten Methoden zu werfen und bietet die Möglichkeit, zu überprüfen, ob bestimmte Methoden aufgerufen wurden / nicht genannt.

Stub . Wie eine Mock-Klasse, mit der Ausnahme, dass sie nicht über die Fähigkeit zur Verfügung stellen, um sicherzustellen, dass Methoden aufgerufen wurden / nicht genannt

Mocks und Stubs Hand erzeugt oder durch einen Mockframework erzeugt werden. Gefälschte Klassen werden von Hand gefertigt. Ich benutze Mocks in erster Linie Wechselwirkungen zwischen meiner Klasse und abhängigen Klassen zu überprüfen. Ich benutze Stubs, wenn ich die Wechselwirkungen überprüft haben, und bin zu testen alternative Pfade durch meinen Code. Ich benutze gefälschte Klassen in erster Linie zu abstrahieren aus Datenabhängigkeiten oder wenn Mocks / Stubs ist zu langweilig jedes Mal einzurichten.

War es hilfreich?

Lösung

Sie können einige Informationen bekommen:

Martin Fowler über Mock und Stub

Gefälschte Objekte haben tatsächlich Implementierungen arbeiten, aber in der Regel einige Abkürzung nehmen, die sie nicht geeignet für die Produktion macht

Stubs bieten Konserven Antworten auf Anrufe während der Prüfung, in der Regel gar nicht zu irgendetwas außerhalb reagiert, was in für den Test programmiert ist. Stubs können auch Informationen über Anrufe, wie ein E-Mail-Gateway-Stub-Datensatz, der die Nachrichten, die er ‚gesendet‘, oder vielleicht nur erinnert, wie viele Nachrichten es gesendet ".

Mocks sind, was wir hier reden. Objekte mit Erwartungen vorprogrammiert, die eine Spezifikation der Anrufe bilden sie erwartet werden, erhalten

xunitpattern :

Gefälschte . Wir erwerben oder eine sehr leichte Implementierung der gleichen Funktionalität, die von einer Komponente, die das SUT abhängt und anweisen, die SUT zu verwenden, um es anstelle der echten

als vorgesehen bauen

Stub : Diese Implementierung ist so konfiguriert, Anrufe aus dem SUT mit den Werten (oder Ausnahmen) zu reagieren, die die Ungeprüfte Kodex ausüben (siehe Produktion Bugs auf Seite X) im SUT. Ein wichtiger Hinweis für die Verwendung eines Test-Stub Ungeprüfte-Code durch die Unfähigkeit verursacht wird, die die indirekten Eingänge des SUT zu steuern

Mock Object , die die gleiche Schnittstelle wie ein Objekt implementiert, auf dem das SUT (System Under Test) abhängig ist. Wir können ein Mock-Objekt als Beobachtungspunkt verwenden, wenn wir Verhalten Verification tun müssen, um eine Ungeprüfte Anforderung zu vermeiden, (siehe Herstellung Bugs auf Seite X), verursacht durch die Unfähigkeit, Nebenwirkungen von Aufrufen Methoden auf dem SUT zu beobachten.

Persönlich

Ich versuche, durch die Verwendung zu vereinfachen: Mock und Stub. Ich benutze Mock, wenn es ein Ziel ist, die einen Wert zurückgibt, der auf die getesteten Klasse festgelegt ist. Ich benutze Stub eine Schnittstelle oder eine abstrakte Klasse zu imitieren getestet werden. In der Tat ist es nicht wirklich wichtig, was Sie es nennen, sie sind alle Klassen, die nicht in der Produktion verwendet werden, und werden als Utility-Klassen zum Testen verwendet.

Andere Tipps

Stub - ein Objekt, das vordefinierte Antworten auf Methodenaufrufe zur Verfügung stellt.

Mock -. Ein Objekt, auf dem Sie die Erwartungen gesetzt

Fälschungs - ein Objekt mit begrenzten Fähigkeiten (zum Zweck der Prüfung), z.B. ein gefälschter Web-Service.

Test Double ist die allgemeine Bezeichnung für Stubs Mocks und Fälschungen. Aber informell, werden Sie oft hören, wie Leute einfach nennen sie verspottet.

Ich bin überrascht, dass diese Frage um so lange und niemand hat ist bisher eine Antwort bereitgestellt basierend auf Roy Osherove "The Art of Unit Testing" .

"3.1 Einführung Stubs" definiert einen Stummel wie:

  

A-Stub ist ein steuerbarer Ersatz für eine bestehende Abhängigkeits   (Oder Mitarbeiter) im System. Durch die Verwendung eines Stub, können Sie Ihren Code testen, ohne   Umgang direkt mit der Abhängigkeit.

Und definiert den Unterschied zwischen Stubs und verspottet wie:

  

Die Hauptsache über Mocks gegen Stubs zu erinnern ist, dass Mocks wie Stümpfe sind, aber Sie behaupten gegen das Mock-Objekt, während Sie gegen einen Stummel behaupten nicht.

Fälschung ist nur der Name für beide Stubs und Mocks verwendet. Zum Beispiel, wenn Sie über den Unterschied zwischen Stubs und Mocks egal.

Die unterscheidet Weg Osherove zwischen Stubs und spottet, bedeutet, dass jede Klasse als Fälschung zum Testen verwendet sowohl ein Stub oder ein Mock sein kann. Was ist es für einen spezifischen Test hängt ganz davon ab, wie Sie die Kontrollen in Ihrem Test schreiben.

  • Wenn Sie den Test prüft Werte in der Klasse unter Test, oder eigentlich überall, aber die Fälschung wurde die Fälschung als Stub verwendet. Es nur Werte zur Verfügung gestellt für die Klasse im Test zu verwenden, entweder direkt durch durch Anrufe auf sie zurückgegebenen Werte oder indirekt über Nebenwirkungen zu verursachen (in einem gewissen Zustand) als Folge der Anrufe auf sie.
  • Wenn Sie den Test prüft Werte der Fälschung, es wurde als Mock verwendet.

Beispiel eines Tests, wo Klasse FakeX als Stub verwendet:

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

cut.SquareIt;

Assert.AreEqual(25, cut.SomeProperty);

Die fake Instanz als Stub verwendet, weil die Assert nicht fake überhaupt nicht verwendet.

Beispiel für einen Test, bei dem Testklasse X als Mock 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 wird die Assert Wert auf fake überprüft, so dass den gefälschten ein Mock.

Nun, natürlich diese Beispiele sind sehr gekünstelt, aber ich sehe großen Verdienst in dieser Unterscheidung. Es macht Sie wissen, wie Sie Ihre Sachen testen und wo die Abhängigkeiten Ihrer Tests sind.

ich mit Osherove die bestätigen, dass

  

von einer reinen Wartbarkeit Perspektive, in meinen Tests Mocks mit schafft mehr Probleme als sie nicht verwenden. Das ist meine Erfahrung gewesen, aber ich lerne immer etwas Neues.

Die Geltendmachung gegen die Fälschung ist etwas, das Sie wirklich vermeiden wollen, wie es Ihre Tests stark abhängig von der Implementierung einer Klasse macht, die überhaupt nicht die im Test ist. Was bedeutet, dass die Tests für die Klasse ActualClassUnderTest können brechen beginnen, da die Implementierung für ClassUsedAsMock geändert. Und das sendet einen üblen Geruch zu mir. Tests für ActualClassUnderTest sollten vorzugsweise nur brechen, wenn ActualClassUnderTest geändert wird.

Ich stelle fest, dass das Schreiben behauptet gegen die Fälschung ist eine gängige Praxis, vor allem wenn man ein Mockist Art von TDD-Abonnent sind. Ich glaube, ich bin fest mit Martin Fowler im klassizistischen Lager (Siehe Martin Fowler „Mocks sind nicht Stubs“ ) und wie Osherove vermeiden Interaktion Prüfung (die nur durch die Behauptung gegen die Fälschung getan werden kann), so viel wie möglich.

Für Spaß beim Lesen auf, warum Sie Mocks wie hier definiert, Google für „fowler Mockist klassizistischen“ vermeiden sollten. Hier finden Sie eine Fülle von Meinungen finden.

Wie die Top-gestimmt Antwort erwähnt, bespricht Martin Fowler diese Unterschiede in Mocks sind nicht Stubs , und insbesondere in der Tarifstelle der Unterschied zwischen Mocks und Stubs , so stellen Sie sicher, dass die Artikel zu lesen.

Statt sich auf wie diese Dinge sind anders, ich denke, es ist aufschlussreicher ist, sich auf Warum das sind unterschiedliche Konzepte. Jedes besteht für einen anderen Zweck.

Fake

fälschen ist eine Implementierung, die "natürlich", aber nicht "real" verhält. Dies sind Fuzzy-Konzepte und so unterschiedliche Menschen haben unterschiedliche Vorstellungen von dem, was macht die Dinge eine Fälschung.

Ein Beispiel für eine Fälschung ist eine In-Memory-Datenbank (zum Beispiel unter Verwendung von SQLite mit dem :memory: Store). Sie würden dies nie für die Produktion verwenden (da die Daten nicht beibehalten werden), aber es ist völlig ausreichend, wie eine Datenbank in einer Testumgebung zu verwenden. Es ist auch viel leichter als eine „echte“ Datenbank.

Als ein anderes Beispiel, vielleicht verwenden Sie irgendeine Art von Objektspeicher (zum Beispiel Amazon S3) in der Produktion, sondern in einem Test können Sie einfach Objekte auf Dateien auf der Festplatte speichern; dann „auf der Festplatte speichern“ Implementierung würde eine Fälschung sein. (Oder Sie könnten sogar fälschen die durch den Betrieb „auf der Festplatte speichern“ unter Verwendung eines In-Memory-Dateisystem statt.)

Als ein drittes Beispiel vorstellen, ein Objekt, das einen Cache-API zur Verfügung stellt; ein Objekt, das die richtige Schnittstelle implementiert, aber das führt einfach kein Caching auf alle, aber immer wieder eine Cache-Miss eine Art Fake sein würde.

Der Zweck einer Fälschung ist nicht , um das Verhalten des Systems unter Test zu beeinflussen , sondern auf vereinfacht die Implementierung des Tests (durch unnötige oder Schwergewichts-Abhängigkeiten zu entfernen).

Stubs

Stub ist eine Implementierung, die "unnatürliche" verhält. Es ist so vorkonfiguriert, (in der Regel durch die Test-Set-up) auf bestimmte Eingänge mit spezifischen Ausgaben zu reagieren.

Der Zweck eines Stub ist Ihr System unter Test in einen bestimmten Zustand zu erhalten. Zum Beispiel, wenn Sie einen Test für einige Codes schreiben, die mit einem REST-API interagiert, könnten Sie Stub die REST-API mit einer API, die immer eine vorgefertigte Antwort zurückgibt, oder dass reagiert auf eine API-Anforderung mit einem bestimmten Fehler. Auf diese Weise können Tests schreiben könnte, die Behauptungen darüber, wie das System auf diese Zustände reagiert; zum Beispiel die Prüfung der Antwort Ihre Benutzer erhalten, wenn die API einen 404-Fehler zurückgibt.

Ein Stub ist in der Regel nur auf die genauen Wechselwirkungen zu reagieren implementiert Sie es gesagt haben, um zu reagieren. Aber das Hauptmerkmal, dass etwas ein Stub macht, ist sein Zweck : a. Stummel dreht sich alles um Ihren Testfall einrichten

Mocks

Mock ist ähnlich einem Stummel, aber mit Überprüfung hinzugefügt. Der Zweck eines Mock zu machen Aussagen darüber, wie Sie Ihr System im Test interagierten mit der Abhängigkeit .

Zum Beispiel, wenn Sie einen Test für ein System schreiben, die Dateien auf eine Website hochgeladen, können Sie eine bauen Mock , die eine Datei akzeptiert und dass Sie verwenden können, zu behaupten, dass die hochgeladene Datei war richtig. Oder in einem kleineren Maßstab, ist es üblich, ein Modell eines Objekts zu verwenden, um sicherzustellen, dass das zu testende System ruft bestimmte Methoden des verspottet Objekts.

Mocks sind gebunden Interaktion testen , die eine spezifische Testmethodik ist. Leute, die es vorziehen, testen Systemzustand statt System-Interaktionen , wenn überhaupt Mocks sparsam verwenden.

Test verdoppelt

Fake, Stubs und verhöhnt alle gehören zu der Kategorie von Test verdoppelt . Ein Test doppelt so hoch ist jedes Objekt oder System, das Sie in einem Test mit statt etwas anderem. Die meisten AutosZusammengesetzte Software-Tests beinhalten die Verwendung von Test verdoppelt irgendeine Art oder ein anderes. Einige andere Arten von Test verdoppelt umfassen Dummy-Werte , Spione und I / O blackhol .

Um die Verwendung von Stubs und Mocks zu illustrieren, würde Ich mag auch ein Beispiel enthalten, um auf Basis von Roy Osherove des „ The Art of Unit Testing ".

Stellen Sie sich vor, wir eine LogAnalyzer Anwendung, die die einzige Funktionalität von Druckprotokollen hat. Es braucht nicht nur auf einen Web-Service zu sprechen, aber wenn der Web-Service einen Fehler wirft, hat LogAnalyzer den Fehler auf eine andere externe Abhängigkeit zu protokollieren, sie per E-Mail an den Web-Service-Administrator zu senden.

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

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

Wie testen Sie, dass LogAnalyzer den E-Mail-Dienst ruft korrekt, wenn der Web-Service eine Ausnahme auslöst? Hier sind die Fragen wir konfrontiert mit:

  • Wie können wir den Web-Service ersetzen?

  • Wie können wir eine Ausnahme von dem Web-Service zu simulieren, damit wir Testen Sie den Aufruf der E-Mail-Service?

  • Wie wissen wir, dass der E-Mail-Dienst korrekt aufgerufen wurde oder alle?

Wir können mit den ersten beiden Fragen, die von mit einem Stub für den Web-Service beschäftigen. Um das dritte Problem zu lösen, können wir ein Mock-Objekt für den E-Mail-Dienst verwenden .

Eine Fälschung ist ein allgemeiner Begriff, der verwendet werden kann, entweder einen Stub oder einen mock.In unseren Test zu beschreiben, werden wir zwei Fälschungen haben. Man wird der E-Mail-Service Mock sein, die wir überprüfen verwenden, um feststellen, dass die richtigen Parameter an den E-Mail-Dienst gesendet wurden. Der andere wird ein Stummel, dass wir eine Ausnahme verwenden werden von dem Web-Dienst geworfen zu simulieren. Es ist ein Stummel, weil wir nicht die Web-Service-Fälschung werden mit dem Testergebnis zu überprüfen, nur der Test, um sicherzustellen, korrekt ausgeführt wird. Der E-Mail-Service ist ein Mock, weil wir gegen sie behaupten werden, dass es 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);
 }
}

Es ist eine Frage der Herstellung der Tests ausdrucksstark. Ich habe Erwartungen auf einem Mock, wenn ich den Test will eine Beziehung zwischen zwei Objekten zu beschreiben. I Stummel Rückgabewerte, wenn ich ein unterstützende Objekt Einrichten mich zum interessanten Verhalten im Test zu erhalten.

das, was Sie auf ihm behaupten, heißt ein Mock Objekt und alles andere, was nur den Testlauf half, ist ein Stub .

Wenn Sie sind vertraut mit Arrange-Act-Assert, dann einer Art und Weise zu erklären, den Unterschied zwischen Stub und Mock, die für Sie nützlich sein könnten, ist, dass Stubs gehören zu dem Abschnitt ordnen, wie sie für die Vermittlung Eingangszustand sind, und gehören Mocks zum assert Abschnitt, da sie für die Geltendmachung Ergebnisse gegen sind.

Dummies tun nichts. Sie sind nur für Parameterlisten füllen, so dass Sie nicht undefiniert oder null Fehler erhalten. Sie existieren auch in streng typisierten Sprachen den Typprüfer zu erfüllen, so dass Sie erlaubt werden können, zu kompilieren und auszuführen.

Stub und fälschen sind Objekte, dass sie ihre Reaktion auf Eingabeparametern basierenden variieren kann. der wesentliche Unterschied zwischen ihnen ist, dass eine Fälschung zu einer Implementierung der realen Welt näher ist als ein Stummel. Stubs enthält im Allgemeinen hart codierte Antworten auf eine erwartete Anforderung. Lassen Sie sehen ein Beispiel:

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;
  }
 }
}

Mock ist ein Schritt von Fälschungen und Stubs. Mocks bieten die gleiche Funktionalität wie Stubs sind aber komplexer. Sie können Regeln für sie definiert haben, in welcher Reihenfolge Methoden auf ihre API diktieren muss aufgerufen werden. Die meisten Mocks können verfolgen, wie oft eine Methode aufgerufen wurde und kann auf diese Informationen reagieren basiert. Mocks weiß in der Regel den Kontext jeden Anruf und kann in unterschiedlichen Situationen unterschiedlich reagieren. Aus diesem Grund, spottet eine gewisse Kenntnis der Klasse benötigen sie verspotten. ein Stub kann verfolgt im allgemeinen nicht, wie oft eine Methode aufgerufen wurde oder eine Folge von Verfahren in welcher Reihenfolge genannt. Ein Mock wie folgt aussieht:

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;
 }

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top