Imitation of the first call failed, second call completed

I want to use Mockito to test the (simplified) code below. I do not know how to tell Mokito a failure the first time, and then succeed a 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 set up a success test with:

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

And the test with an error:

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

But how can I verify that if it works once (or twice), then it will succeed?

+83
java mockito
Aug 2 2018-12-12T00:
source share
5 answers

From documents :

Sometimes we need to stub with a different return value / exception for the same method call. A typical use case may be mocking iterators. The original version of Mockito did not have this feature to promote simple mockery. For example, instead of iterators, you can use Iterable or just collections. They offer natural corking methods (e.g. using real collections). In rare scenarios, consecutive calls can be useful:

 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 need to:

 when(myMock.doTheCall()) .thenReturn("You failed") .thenReturn("Success"); 
+191
Aug 02 2018-12-12T00:
source share

The shortest way to write what you need is

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

When you pass multiple arguments to thenReturn like this, each argument will be used no more than once, except for the very last argument, which is used as many times as necessary. For example, in this case, if you make a call 4 times, you will receive “Success”, “you have not completed”, “you have not completed”, “you have not completed”.

+27
Aug 03 2018-12-12T00:
source share

Since the comment associated with this is difficult to read, I will add a formatted answer.

If you are trying to do this with the void function, which simply throws an exception with the next step without behavior, then you should do something like this:

 Mockito.doThrow(new Exception("MESSAGE")) .doNothing() .when(mockService).method(eq()); 
+14
Dec 21 '16 at 22:09
source share

To add to this and this answer, you can also use a loop to chain fake calls. This is useful if you need to mock the same thing several times or in some way.

For example (although far-fetched):

 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()); 
+1
Jan 25 '18 at 11:17
source share

I have a different situation, I wanted to mock up the void function for the first call and run it normally on the second call.

This works for me:

 Mockito.doThrow(new RuntimeException("random runtime exception")).doCallRealMethod().when(object).method(Mockito.any()); 
0
Jun 19 '19 at 1:17
source share



All Articles