我想使用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");
但是,如果它失败了一次(或两次),然后成功了,我该怎么测试呢?
来自文档:
有时,我们需要为同一个方法调用使用不同的返回值/异常来存根。典型的用例可能是模拟迭代器。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");
编写所需内容的最短方法是
when(myMock.doTheCall()).thenReturn("Success", "you failed");
当您像这样向thenReturn
提供多个参数时,每个参数最多使用一次,但最后一个参数除外,它会根据需要使用多次。例如,在这种情况下,如果你打了4次电话,你会得到"Success"、"you failed"、"you failed"one_answers"you failure"。
由于与此相关的注释很难阅读,我将添加一个格式化的答案。
如果您尝试使用void
函数来执行此操作,该函数只抛出一个异常,然后执行无行为步骤,那么您将执行以下操作:
Mockito.doThrow(new Exception("MESSAGE"))
.doNothing()
.when(mockService).method(eq());
我有一个不同的情况,我想在第一次调用时模拟void
函数,并在第二次调用时正常运行它。
这对我有效:
Mockito.doThrow(new RuntimeException("random runtime exception"))
.doCallRealMethod()
.when(spy).someMethod(Mockito.any());
要添加这个和这个答案,还可以使用循环来链接模拟调用。如果您需要多次模拟同一事物,或者以某种模式进行模拟,这将非常有用。
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());
最短的是
doReturn("Fail", "Success").when(myMock).doTheCall();