是否有一种方法可以让存根方法在后续调用时返回不同的对象?我希望这样做是为了测试来自ExecutorCompletionService的不确定响应。也就是说,测试不管方法的返回顺序如何,结果都保持不变。

我要测试的代码看起来像这样。

// 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 (...) { }        
}

当前回答

与8年前@[Igor Nikolaev]的答案相关,使用Java 8中的lambda表达式可以在一定程度上简化answer的使用。

when(someMock.someMethod()).thenAnswer(invocation -> {
    doStuff();
    return;
});

或者更简单地说:

when(someMock.someMethod()).thenAnswer(invocation -> doStuff());

其他回答

你可以使用thenAnswer方法(当与when链接时):

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

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

        return 2;
    }
});

或者使用等效的静态doAnswer方法:

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

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

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

正如前面指出的,几乎所有的调用都是可链的。

所以你可以打电话

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();

更多信息在Mockito的文档。

如果你有一个值的动态列表,你可以使用AdditionalAnswers.returnsElementsOf:

import org.mockito.AdditionalAnswers;

when(mock.method()).thenAnswer(AdditionalAnswers.returnsElementsOf(myListOfValues));

与8年前@[Igor Nikolaev]的答案相关,使用Java 8中的lambda表达式可以在一定程度上简化answer的使用。

when(someMock.someMethod()).thenAnswer(invocation -> {
    doStuff();
    return;
});

或者更简单地说:

when(someMock.someMethod()).thenAnswer(invocation -> doStuff());

这里是BDD风格的工作示例,非常简单和清晰

given(carRepository.findByName(any(String.class))).willReturn(Optional.empty()).willReturn(Optional.of(MockData.createCarEntity()));