我想使用Mockito来测试下面的(简化)代码。我不知道如何告诉Mockito第一次失败,然后第二次成功。
for(int i = 1; i < 3; i++) {
String ret = myMock.doTheCall();
if("Success".equals(ret)) {
log.write("success");
} else if ( i < 3 ) {
log.write("failed, but I'll try again. attempt: " + i);
} else {
throw new FailedThreeTimesException();
}
}
我可以使用以下方式设置成功测试:
Mockito.when(myMock).doTheCall().thenReturn("Success");
失败测试:
Mockito.when(myMock).doTheCall().thenReturn("you failed");
但我如何测试如果它失败一次(或两次)然后成功,那很好吗?
答案 0 :(得分:187)
来自the docs:
有时我们需要为同一个方法调用存根不同的返回值/异常。典型的用例可能是模拟迭代器。 Mockito的原始版本没有这个功能来促进简单的嘲笑。例如,可以使用Iterable或简单集合代替迭代器。那些提供了自然的存根方式(例如使用真实的集合)。在极少数情况下,存根连续调用可能很有用,但是:
when(mock.someMethod("some arg")) .thenThrow(new RuntimeException()) .thenReturn("foo"); //First call: throws runtime exception: mock.someMethod("some arg"); //Second call: prints "foo" System.out.println(mock.someMethod("some arg"));
所以在你的情况下,你想要:
when(myMock.doTheCall())
.thenReturn("You failed")
.thenReturn("Success");
答案 1 :(得分:27)
写出你想要的东西的最短路是
when(myMock.doTheCall()).thenReturn("Success", "you failed");
当您向thenReturn
提供多个参数时,每个参数最多只会使用一次,最后一个参数除外,根据需要多次使用。例如,在这种情况下,如果您拨打电话4次,您将获得“成功”,“您失败”,“您失败”,“您失败”。
答案 2 :(得分:14)
由于与此相关的评论难以阅读,我将添加格式化答案。
如果你试图用一个只抛出异常的void函数来执行此操作,然后执行no行为步骤,那么你会这样做:
Mockito.doThrow(new Exception("MESSAGE"))
.doNothing()
.when(mockService).method(eq());
答案 3 :(得分:1)
要添加到this和this答案,您还可以使用循环来链接模拟的调用。如果您需要多次模拟相同的事物,或者以某种模式进行模拟,这非常有用。
例如(虽然是一个牵强的):
import org.mockito.stubbing.Stubber;
Stubber stubber = doThrow(new Exception("Exception!"));
for (int i=0; i<10; i++) {
if (i%2 == 0) {
stubber.doNothing();
} else {
stubber.doThrow(new Exception("Exception"));
}
}
stubber.when(myMockObject).someMethod(anyString());
答案 4 :(得分:0)
我的情况有所不同,我想为第一个调用模拟void
函数,并在第二个调用中正常运行它。
这对我有用:
Mockito.doThrow(new RuntimeException("random runtime exception")).doCallRealMethod().when(object).method(Mockito.any());
答案 5 :(得分:0)
最短的是
doReturn("Fail", "Success").when(myMock).doTheCall();