163

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

但是我如何测试它是否失败了一次(或两次)然后成功了,没关系?

4

6 回答 6

308

文档

有时我们需要为同一个方法调用使用不同的返回值/异常存根。典型的用例可能是模拟迭代器。原始版本的 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");
于 2012-08-02T20:51:07.627 回答
46

写你想要的最短的方法是

when(myMock.doTheCall()).thenReturn("Success", "you failed");

当您thenReturn为此提供多个参数时,每个参数将最多使用一次,除了最后一个参数,它会根据需要使用多次。例如,在这种情况下,如果您拨打 4 次电话,您将获得“成功”、“您失败”、“您失败”、“您失败”。

于 2012-08-03T05:06:12.663 回答
38

由于与此相关的评论很难阅读,我将添加一个格式化的答案。

如果您尝试使用void仅引发异常的函数执行此操作,然后执行无行为步骤,那么您将执行以下操作:

Mockito.doThrow(new Exception("MESSAGE"))
            .doNothing()
            .when(mockService).method(eq());
于 2016-12-21T22:09:00.930 回答
8

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

这对我有用:

Mockito.doThrow(new RuntimeException("random runtime exception"))
       .doCallRealMethod()
       .when(spy).someMethod(Mockito.any());
于 2019-06-19T01:17:02.380 回答
6

要添加到这个这个答案,您还可以使用循环来链接模拟调用。如果您需要多次模拟同一事物或以某种模式模拟,这将很有用。

例如(虽然有点牵强):

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());
于 2018-01-25T11:17:17.437 回答
1

最短的是

doReturn("Fail", "Success").when(myMock).doTheCall();
于 2021-06-13T17:43:22.443 回答