模拟第一次调用失败,第二次调用成功

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

但是,如果它失败一次(或两次)然后成功了,我怎么才能测试它是正常的呢?

125481 次浏览

来自 那些文件:

有时我们需要为同一个方法调用使用不同的返回值/异常存根。典型的用例可能是模仿迭代器。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次电话,你会得到“成功”,“你失败了”,“你失败了”,“你失败了”。

由于与此相关的注释难以阅读,我将添加一个格式化的答案。

如果使用 void函数执行此操作,该函数只抛出一个异常,然后执行一个无行为步骤,那么您将执行以下操作:

Mockito.doThrow(new Exception("MESSAGE"))
.doNothing()
.when(mockService).method(eq());

要添加到 这个这个应答,还可以使用循环来链接模拟调用。如果您需要多次模仿同一件事情,或者以某种模式模仿,那么这很有用。

例如:

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

我有一个不同的情况,我想为第一次调用模拟一个 void函数,并在第二次调用时正常运行它。

这对我有用:

Mockito.doThrow(new RuntimeException("random runtime exception"))
.doCallRealMethod()
.when(spy).someMethod(Mockito.any());

最短的应该是

doReturn("Fail", "Success").when(myMock).doTheCall();