519 Stimmen

Verwendung von Mockito mit mehreren Aufrufen der gleichen Methode mit den gleichen Argumenten

Gibt es eine Möglichkeit, eine Stubbed-Methode bei nachfolgenden Aufrufen unterschiedliche Objekte zurückgeben zu lassen? Ich würde dies gerne tun, um unbestimmte Antworten von einer ExecutorCompletionService . d.h. zu testen, dass unabhängig von der Rückgabereihenfolge der Methoden das Ergebnis konstant bleibt.

Der Code, den ich testen möchte, sieht ungefähr so aus.

// Create an completion service so we can group these tasks together
ExecutorCompletionService<T> completionService =
        new ExecutorCompletionService<T>(service);

// Add all these tasks to the completion service
for (Callable<T> t : ts)
    completionService.submit(request);

// As an when each call finished, add it to the response set.
for (int i = 0; i < calls.size(); i ++) {
    try {
        T t = completionService.take().get();
        // do some stuff that I want to test
    } catch (...) { }        
}

981voto

Dawood ibn Kareem Punkte 72413

Wie wäre es mit

when( method-call ).thenReturn( value1, value2, value3 );

Sie können beliebig viele Argumente in die Klammern von thenReturn setzen, sofern sie alle vom richtigen Typ sind. Der erste Wert wird beim ersten Aufruf der Methode zurückgegeben, dann die zweite Antwort usw. Der letzte Wert wird wiederholt zurückgegeben, sobald alle anderen Werte aufgebraucht sind.

351voto

Igor Nikolaev Punkte 4397

Sie können dies mit der Option thenAnswer Methode (bei Verkettung mit when ):

when(someMock.someMethod()).thenAnswer(new Answer() {
    private int count = 0;

    public Object answer(InvocationOnMock invocation) {
        if (count++ == 1)
            return 1;

        return 2;
    }
});

Oder mit dem gleichwertigen, statischen doAnswer Methode:

doAnswer(new Answer() {
    private int count = 0;

    public Object answer(InvocationOnMock invocation) {
        if (count++ == 1)
            return 1;

        return 2;
    }
}).when(someMock).someMethod();

257voto

Raystorm Punkte 5731

Als zuvor darauf hingewiesen fast alle Aufrufe sind verkettbar.

Sie könnten also anrufen

when(mock.method()).thenReturn(foo).thenReturn(bar).thenThrow(new Exception("test"));

//OR if you're mocking a void method and/or using spy instead of mock

doReturn(foo).doReturn(bar).doThrow(new Exception("Test").when(mock).method();

Mehr Infos unter Mockitos Dokumentation .

95voto

Volodymyr Kozubal Punkte 1270

Fast alle Aufrufe sind verkettbar:

doReturn(null).doReturn(anotherInstance).when(mock).method();

59voto

epox Punkte 6406

BDD-Stil:

import static org.mockito.BDDMockito.given;
        ...

        given(yourMock.yourMethod()).willReturn(1, 2, 3);

Klassischer Stil:

import static org.mockito.Mockito.when;
        ...

        when(yourMock.yourMethod()).thenReturn(1, 2, 3);

Expliziter Stil:

        ...

        when(yourMock.yourMethod())
            .thenReturn(1)
            .thenReturn(2)
            .thenReturn(3);

Abhängig von einem Argument

Angenommen, wir haben 2 Argumente und prüfen die Größe des 2. (Listen-)Argumentes:

        ...

        when(yourMock.yourMethod(any(), anyList()))
             .thenAnswer(args -> ((List) args.getArgument(1)).size() < 2
                                 ? 1
                                 : 3);

args sind Objects, also müssen wir ein arg auf unseren Typ casten. Ich caste ^^^ auf (List) in meinem Fall.

BDD

        ...

        given(yourMock.yourMethod(any(), anyList()))
             .willAnswer(args -> ((List) args.getArgument(1)).size() < 2
                                 ? 1
                                 : 3);

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