使用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);