'MOCKITO - Change the exception thrown based on number of times the method is called

I want to throw a specific exception for the first 5 times the method is executed. Afterwards, I want to throw another exception.

Ideally, I have this code snippet, which obviously doesn't work

int count = 0;
int max = 5;

@Test
public void myTest(){
   ...
   doThrow(count++ < max ? myException1 : myException2).when(myClass).myMethod()
   ...
}

How can I make it work?



Solution 1:[1]

You can use the thenThrow(Throwable... throwables) method on the OngoingStubbing instance returned by Mockito.when(...).
The method accepts a var-args that are the exceptions to throw consecutively when the mocked method is invoked.

@Test
public void myTest(){
   // ...
   Mockito.when(myClass.myMethod())
          .thenThrow( myException1, 
                      myException1, 
                      myException1, 
                      myException1, 
                      myException1,
                      myException2);
   // ...
}

or by chaining OngoingStubbing.thenThrow() invocations as the method actually returns a OngoingStubbing object :

@Test
public void myTest(){
   // ...
   Mockito.when(myClass.myMethod())
          .thenThrow(myException1)
          .thenThrow(myException1)
          .thenThrow(myException1)
          .thenThrow(myException1)
          .thenThrow(myException1)
          .thenThrow(myException2);
   // ...
}

Solution 2:[2]

You can return exception at first call and another thing at second call:

when(myMock.myMethod(any()))
.thenThrow(new MyFirstException())
.thenThrow(new MySecondException())
.thenReturn(new MyObject();

This approach is useful in testing recursively called methods.

In the end I suggest checking if the method was called with the correct amount of times.

verify(myMock, times(3)).myMethod(any());

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Rafael Veck