Simulate first call fails, second call succeeds

jb. picture jb. · Aug 2, 2012 · Viewed 83k times · Source

I want to use Mockito to test the (simplified) code below. I don't know how to tell Mockito to fail the first time, then succeed the second time.

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

I can setup the success test with:

Mockito.when(myMock).doTheCall().thenReturn("Success");

And the failure test with:

Mockito.when(myMock).doTheCall().thenReturn("you failed");

But how can I test that if it fails once (or twice) then succeeds, it's fine?

Answer

Jon Skeet picture Jon Skeet · Aug 2, 2012

From the docs:

Sometimes we need to stub with different return value/exception for the same method call. Typical use case could be mocking iterators. Original version of Mockito did not have this feature to promote simple mocking. For example, instead of iterators one could use Iterable or simply collections. Those offer natural ways of stubbing (e.g. using real collections). In rare scenarios stubbing consecutive calls could be useful, though:

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

So in your case, you'd want:

when(myMock.doTheCall())
   .thenReturn("You failed")
   .thenReturn("Success");