1373 Stimmen

Was ist der Unterschied zwischen einer Attrappe und einem Stummel?

Ich habe verschiedene Artikel über Mocking vs Stubbing in Tests gelesen, einschließlich Martin Fowlers Spötteleien sind keine Spötteleien aber ich verstehe den Unterschied immer noch nicht.

8voto

Kasper Punkte 627

Es gibt viele gültige Antworten, aber ich denke, es lohnt sich, dieses Formular von Onkel Bob zu erwähnen: https://8thlight.com/blog/uncle-bob/2014/05/14/TheLittleMocker.html

die beste Erklärung überhaupt mit Beispielen!

7voto

davidxxx Punkte 114488

Eine Attrappe ist sowohl ein eine technische und eine funktionale Objekt.

Der Spott ist technisch . Es wird in der Tat von einer Mocking-Bibliothek (EasyMock, JMockit und neuerdings auch Mockito sind dafür bekannt) erstellt, dank Bytecode-Generierung .
Die Mock-Implementierung ist generiert in einer Weise, die es uns ermöglicht Instrument Es soll einen bestimmten Wert zurückgeben, wenn eine Methode aufgerufen wird, aber auch einige andere Dinge, wie z.B. die Überprüfung, ob eine Mock-Methode mit bestimmten Parametern (strict check) oder ohne Parameter (no strict check) aufgerufen wurde.

Instanziierung einer Attrappe :

@Mock Foo fooMock

Aufzeichnung eines Verhaltens :

when(fooMock.hello()).thenReturn("hello you!");

Überprüfen eines Aufrufs :

verify(fooMock).hello()

Dies ist eindeutig nicht die natürliche Art und Weise, die Foo-Klasse/das Foo-Verhalten zu instanziieren/überschreiben. Deshalb verweise ich auf einen technischen Aspekt.

Aber die Attrappe ist auch funktional weil sie eine Instanz der Klasse ist, die wir vom SUT isolieren müssen. Und mit aufgezeichneten Verhaltensweisen können wir sie im SUT auf die gleiche Weise verwenden wie einen Stub.


Der Stumpf ist nur eine funktionale 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 Verhaltensfixtures, die während unserer Unit-Tests benötigt werden, explizit definiert werden müssen.
Zum Beispiel zum Stub hello() müsste die Unterklasse Foo Klasse (oder implementiert ihre Schnittstelle, die sie hat) und zu überschreiben hello() :

public class HelloStub extends Hello{    
  public String hello { 
      return "hello you!"; 
  }
}

Wenn ein anderes Testszenario einen anderen Rückgabewert erfordert, müssen wir wahrscheinlich eine generische Methode zum Setzen des Rückgabewerts definieren:

public class HelloStub extends Hello{    
  public HelloStub(String helloReturn){
       this.helloReturn = helloReturn;
  }
  public String hello { 
      return helloReturn; 
  }
}

Anderes Szenario: Wenn ich eine Seiteneffekt-Methode (ohne Rückgabe) hätte und überprüfen würde, ob diese Methode aufgerufen wurde, sollte ich wahrscheinlich einen Booleschen Wert oder einen Zähler in der Stub-Klasse hinzufügen, um zu zählen, wie oft die Methode aufgerufen wurde.


Schlussfolgerung

Der Stub erfordert oft viel Overhead/Code für Ihren Unit-Test. Was Mock verhindert dank der Bereitstellung von Aufzeichnungs-/Verifizierungsfunktionen out of the box.
Aus diesem Grund wird der Stub-Ansatz heutzutage in der Praxis nur noch selten verwendet, da es hervorragende Mock-Bibliotheken gibt.


Über den Artikel von Martin Fowler : Ich halte mich nicht für einen "mockistischen" Programmierer, obwohl ich Mocks verwende und Stubs vermeide.
Aber ich verwende Mock, wenn es wirklich erforderlich ist (lästige Abhängigkeiten), und ich bevorzuge Test Slicing und Mini-Integrationstests, wenn ich eine Klasse mit Abhängigkeiten teste, bei denen Mocking einen Overhead bedeuten würde.

5voto

ahmednabil88 Punkte 14906

Plus nützliche Antworten, Eine der wichtigsten starker Vorteil von Mocks gegenüber Subs

Wenn der Kollaborateur [von dem der Hauptcode abhängt] ist nicht unter unserer Kontrolle (z. B. aus einer Bibliothek eines Drittanbieters),
In diesem Fall, stub ist schwieriger zu schreiben als mock .

4voto

Harry Punkte 4555

Stummel hilft uns bei der Durchführung von Tests. Wie? Es gibt Werte, die bei der Durchführung von Tests helfen. Diese Werte sind selbst nicht real und wir haben diese Werte nur erstellt, um den Test durchzuführen. Wir erstellen zum Beispiel eine HashMap, die uns Werte liefert, die den Werten in der Datenbanktabelle ähneln. Anstatt also direkt mit der Datenbank zu interagieren, interagieren wir mit der Hashmap.

Mock ist ein Fake-Objekt, das den Test ausführt. wo wir assert.

4voto

Lho Ben Punkte 1905

Ein Stub ist ein Testdouble, das Werte an das SUT zurückgibt.

Ein Mock ist ein Testdouble, das ein Test verwendet, um zu überprüfen, ob das SUT eine Abhängigkeit korrekt aufruft.

Außerdem ist eine Attrappe oft ein Stummel

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X