Spott gegen Spionage in spöttischen Rahmenbedingungen

131

In Verspottungs-Frameworks können Sie ein Objekt verspotten oder es ausspionieren . Was ist der Unterschied zwischen den beiden und wann würde / sollte ich einen über den anderen verwenden?

Wenn ich zum Beispiel Mockito betrachte , sehe ich, dass ähnliche Dinge mit Spionen und Spott gemacht werden , aber ich bin mir nicht sicher, ob zwischen beiden unterschieden wird.

Vivin Paliath
quelle

Antworten:

156

Das Scheinobjekt ersetzt die verspottete Klasse vollständig und gibt aufgezeichnete oder Standardwerte zurück. Sie können Mock aus "dünner Luft" erstellen. Dies wird hauptsächlich beim Testen von Einheiten verwendet.

Beim Spionieren nehmen Sie ein vorhandenes Objekt und "ersetzen" nur einige Methoden. Dies ist nützlich, wenn Sie eine große Klasse haben und nur bestimmte Methoden verspotten möchten (teilweise Verspottung). Lassen Sie mich die Mockito-Dokumentation zitieren :

Sie können Spione von realen Objekten erstellen. Wenn Sie den Spion verwenden, werden die realen Methoden aufgerufen (es sei denn, eine Methode wurde gestoppt).

Echte Spione sollten sorgfältig und gelegentlich eingesetzt werden , beispielsweise beim Umgang mit Legacy-Code.

Verwenden Sie im Zweifelsfall Mocks.

Tomasz Nurkiewicz
quelle
1
Danke dir! Das macht es viel klarer. So spottet nie verhöhnte das eigentliche Objekt übertragen wird jemals , aber Spione tun.
Vivin Paliath
7
Mocks haben kein "tatsächliches Objekt" - der Mock wird von Anfang an erstellt.
Carl Manaster
4
Gibt es eine Erklärung dafür, warum Mockito davor warnt, ständig Spione einzusetzen? Ich sehe, dass sie sagen, Mocks zu bevorzugen, aber ich bin mir nicht sicher, warum.
Matt
8
Ich bin nicht sicher, aber vielleicht, weil sie "Mockito" und nicht "Spyito" sind: D
Tippfehler
16

Mockito warnt davor, dass teilweises Verspotten keine gute Praxis ist, und Sie sollten Ihre objektorientierte Architektur überarbeiten. Spion (oder teilweise Verspottung) wird empfohlen, um Legacy-Code zu testen .

Suelmar Zanetti
quelle
16

Ich werde versuchen, dies anhand eines Beispiels zu erklären:

// Difference between mocking, stubbing and spying
@Test
public void differenceBetweenMockingSpyingAndStubbing() {
    List list = new ArrayList();
    list.add("abc");
    assertEquals(1, list.size());

    List mockedList = spy(list);
    when(mockedList.size()).thenReturn(10);
    assertEquals(10, mockedList.size());
}

Hier hatten wir ein anfängliches reales Objekt list, in dem wir ein Element hinzugefügt haben und erwartet haben, dass die Größe eins ist.

Wir spionieren reale Objekte aus, was bedeutet, dass wir anweisen können, welche Methode gestoppt werden soll . Also haben wir erklärt, dass wir die Methode gestoppt haben - size()für ein Spionageobjekt, das 10 zurückgibt , unabhängig von der tatsächlichen Größe.

Auf den Punkt gebracht, werden Sie auszuspionieren realen Objekt und Stummel einige der Methoden .

user2775185
quelle
2

Referenz: http://javapointers.com/tutorial/difference-between-spy-and-mock-in-mockito/

Wenn Sie Scheinobjekte verwenden, ist das Standardverhalten der Methode, wenn sie nicht stub ist, nichts zu tun. Einfach bedeutet, wenn es eine void-Methode ist, wird es nichts tun, wenn Sie die Methode aufrufen, oder wenn es eine Methode mit einer Rückgabe ist, kann es null, leer oder den Standardwert zurückgeben.

Da es sich bei Spionageobjekten natürlich um eine echte Methode handelt, wird das echte Methodenverhalten aufgerufen, wenn Sie die Methode nicht stubben. Wenn Sie die Methode ändern und verspotten möchten, müssen Sie sie stubben.

Jerry C.
quelle
2

Dummy- Objekte werden herumgereicht, aber nie benutzt. Normalerweise werden sie nur zum Füllen von Parameterlisten verwendet.

Gefälschte Objekte haben tatsächlich funktionierende Implementierungen, verwenden jedoch normalerweise eine Verknüpfung, die sie für die Produktion nicht geeignet macht (eine In-Memory-Datenbank ist ein gutes Beispiel).

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.

Spione sind Stubs, die auch einige Informationen aufzeichnen, die darauf basieren, wie sie genannt wurden. Eine Form davon könnte ein E-Mail-Dienst sein, der aufzeichnet, wie viele Nachrichten gesendet wurden.

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

Mocks Aren't Stubs von Martin Fowler

Mohsen
quelle
1

Spione haben zwei Definitionen. Zum einen wird die reale Methode aufgerufen, zum anderen wird keine Funktionalität aufgerufen und es werden nur null oder null äquivalente Werte zurückgegeben, aber Methoden wurden aufgerufen, und ihr Status wurde aufgezeichnet, wie die Methode x y-mal aufgerufen wurde.

John Heilman
quelle
0

Wenn Sie in Mockito der Instanzvariablen von Mock Object ein Objekt zuweisen, wirkt sich dies nicht auf Mock Object aus.

Wenn Sie jedoch im Fall von Spy ein Objekt der Instanzvariablen von Spy Object zuweisen, wirkt sich dies auf Spy Object aus, da Spy sich wie eine Echtzeit-Objektänderung verhält.

Als Referenzbeispiel dienen

@RunWith(MockitoJUnitRunner.class)
public class MockSpyExampleTest {

    @Mock
    private List<String> mockList;

    @Spy
    private List<String> spyList = new ArrayList();

    @Test
    public void testMockList() {
        //by default, calling the methods of mock object will do nothing
        mockList.add("test");
        assertNull(mockList.get(0));
    }

    @Test
    public void testSpyList() {
        //spy object will call the real method when not stub
        spyList.add("test");
        assertEquals("test", spyList.get(0));
    }
}
Yasir Shabbir Choudhary
quelle