使用Mockito多次调用具有相同参数的相同方法

有没有一种方法来让后续调用中的stubbed方法返回不同的对象? 我想这样做来testingExecutorCompletionService非确定性响应。 即为了testing,不pipe方法的返回顺序如何,结果保持不变。

我正在testing的代码看起来像这样。

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

您可以使用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( method-call ).thenReturn( value1, value2, value3 ); 

您可以在随后的回车的括号中添加尽可能多的参数,前提是它们都是正确的types。 第一个值将在第一次调用方法时返回,然后是第二个答案,依此类推。 一旦所有其他值用完,最后的值将被重复返回。

你甚至可以像这样链接doReturn()方法调用

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

可爱是不是:)

如前所述,几乎所有的电话都是可链接的。

所以你可以打电话

 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的文件更多信息。

我已经实现了一个MultipleAnswer类,可以帮助我在每个调用中存储不同的答案。 这里的一段代码:

 private final class MultipleAnswer<T> implements Answer<T> { private final ArrayList<Answer<T>> mAnswers; MultipleAnswer(Answer<T>... answer) { mAnswers = new ArrayList<>(); mAnswers.addAll(Arrays.asList(answer)); } @Override public T answer(InvocationOnMock invocation) throws Throwable { return mAnswers.remove(0).answer(invocation); } } 

以下可以用作通用方法来在不同的方法调用中返回不同的参数。 只有我们需要做的是我们需要传递一个数组的顺序,在每个调用中应该检索对象。

 @SafeVarargs public static <Mock> Answer<Mock> getAnswerForSubsequentCalls(final Mock... mockArr) { return new Answer<Mock>() { private int count=0, size=mockArr.length; public Mock answer(InvocationOnMock invocation) throws throwable { Mock mock = null; for(; count<size && mock==null; count++){ mock = mockArr[count]; } return mock; } } } 

防爆。 getAnswerForSubsequentCalls(mock1, mock3, mock2); 将在第一次调用时返回mock1对象,在第二次调用时返回mock3对象,在第三次调用时返回mock2对象。 应该像when(something()).doAnswer(getAnswerForSubsequentCalls(mock1, mock3, mock2)); 这几乎和when(something()).thenReturn(mock1, mock3, mock2);类似, when(something()).thenReturn(mock1, mock3, mock2);