2013-05-29 2 views
16

Ich verwende die Mockito framework, um Mock-Objekte in meinen JUnit-Tests zu erstellen. Jeder weiß, was Mock Methoden haben sie aufgefordert worden, so bei meinen Tests kann ich schreibenWerden Mock-Objekte für jeden Test zurückgesetzt?

verify(myMock, atLeastOnce()).myMethod(); 

Ich frage mich, ob diese interne Mock Kenntnis das, was es genannt hat, wird über meine Tests bestehen? Wenn es fortbesteht, könnte ich falsche positive Ergebnisse bekommen, wenn ich dieselbe Methode in zwei Tests verwende.

Ein Codebeispiel

@RunWith(MockitoJUnitRunner.class) 
public class EmrActivitiesImplTest { 

    @Mock private MyClass myMock; 

    @Before 
    public void setup() { 
     when(myMock.myMethod()).thenReturn("hello"); 
    } 

    @Test 
    public void test1() { 
     // ..some logic 
     verify(myMock, atLeastOnce()).myMethod(); 
    } 

    @Test 
    public void test2() { 
     // ..some other logic 
     verify(myMock, atLeastOnce()).myMethod(); 
    } 
} 

Mock Zustand beibehalten wird - test2 unabhängig passieren wird, da Methode test1 des verifizieren

bestanden

Mock Zustand zurückgesetzt wird - test2 fehlschlägt, wenn myMock.myMethod() nicht ist

+0

Wenn ich nicht falsch liege, wird Setup einmal aufgerufen, bevor alle Tests ... ja, alle Ihre Tests verwenden das gleiche Mock-Objekt. Sie müssen dieses Objekt am Anfang jeder Testmethode erstellen –

Antwort

20

JUnit erstellt jedes Mal eine neue Instanz der Testklasse, wenn eine neue Testmethode ausgeführt wird, und führt bei jedem Erstellen einer neuen Testklasse die Methode @Before aus. Sie können es einfach testen

@Before 
public void setup() { 
     System.out.println("setup"); 
     when(myMock.myMethod()).thenReturn("hello"); 
} 

Und MockitoJUnitRunner wird eine neue MyMock Mock-Instanz für jede Testmethode

+8

Das ist richtig. ** JUnit ** -Designer wollten eine Testisolierung zwischen den Testmethoden, also erstellt sie eine neue Instanz der Testklasse, um jede Testmethode auszuführen. Beachten Sie, dass der ** TestNG ** -Ersteller einen anderen Weg gewählt hat und die Isolation pro Testklasse gewählt hat, dh es gibt keine Isolation zwischen den Testmethoden eines TestNG-Tests. Daher müssen Instanz-Mocks möglicherweise zwischen den einzelnen Testmethoden zurückgesetzt werden. – Brice

+0

Und das ist ein großes Problem bei der Verwendung von Singletons, weil die Mocks nur für den ersten Test korrekt sind ... –

+0

Haben Sie irgendwo wo dies dokumentiert ist gefunden? Ich habe gewusst, dass dies eine Zeitlang wahr ist, aber nachdem ich jemanden gefragt habe, habe ich gesucht und kann es nirgendwo im Dokument finden. – dsingleton

0

Wenn Sie nur die Mock-Objekte in Ihrem setup initialisieren, können Sie innerhalb jedes Tests verschiedene Funktionen bereitstellen. Sie können es einmalig initialisieren und danach ändern, wie sie sich verhalten bzw. erwarten.

12
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

import static org.mockito.Mockito.*; 

@RunWith(MockitoJUnitRunner.class) 
public class sandbox { 

    @Mock 
    private MyClass myMock; 

    @Before 
    public void setup() { 
     when(myMock.myMethod()).thenReturn("hello"); 
    } 

    @Test 
    public void test1() { 
     myMock.myMethod(); 
     verify(myMock, times(1)).myMethod(); 
    } 

    @Test 
    public void test2() { 
     myMock.myMethod(); 
     verify(myMock, times(1)).myMethod(); 
    } 

} 

Dies geht erstellen. Wenn der Zustand bestehen bleibt, würde der zweite Test fehlschlagen. Wenn Sie es debuggen, würden Sie sehen, dass Sie eine neue Instanz des mocked-Objekts für jeden Test erhalten.

+0

Ja, stimme zu, wenn @RunWith (MockitoJUnitRunner.class) verwendet wird, werden neue Mocks injiziert. – yuranos87