How can I make a mockito mock to perform various actions in sequence?

The following code:

ObjectMapper mapper = Mockito.mock(ObjectMapper.class); Mockito.doThrow(new IOException()).when(mapper).writeValue((OutputStream) Matchers.anyObject(), Matchers.anyObject()); Mockito.doNothing().when(mapper).writeValue((OutputStream) Matchers.anyObject(), Matchers.anyObject()); try { mapper.writeValue(new ByteArrayOutputStream(), new Object()); } catch (Exception e) { System.out.println("EXCEPTION"); } try { mapper.writeValue(new ByteArrayOutputStream(), new Object()); } catch (Exception e) { System.out.println("EXCEPTION"); } 

Expected Result:

AN EXCEPTION

right?

But I get nothing

If I do doThrow after doNothing, I get

AN EXCEPTION
AN EXCEPTION

So, it looks like the last layout is the one that was taken ... I thought it would take the layouts in the order in which they are registered?

I am looking to create a layout, throws an exception for the first time and usually completes the second time ...

+7
java mockito
Nov 20 '13 at 14:29
source share
1 answer

Mockito can drown out sequential behavior with the same parameters - repeating the final instruction forever, but they should all be part of the same chain. Otherwise, Mockito effectively thinks that you have changed your mind and overwritten your previously mocked behavior, which is not a bad feature if you set good default values ​​in the setUp or @Before and want to override them in a specific test case.

General rules for what action Mockito will happen as follows: The most specific chain will be selected that matches all arguments. Within the chain, each action will be executed once (counting several thenReturn values ​​if specified as thenReturn(1, 2, 3) ), and then the last action will be repeated forever.

 // doVerb syntax, for void methods and some spies Mockito.doThrow(new IOException()) .doNothing() .when(mapper).writeValue( (OutputStream) Matchers.anyObject(), Matchers.anyObject()); 

This is the equivalent of thenVerb encoded statements in the more general when syntax, which you correctly avoided here for your void method:

 // when/thenVerb syntax, to mock methods with return values when(mapper.writeValue( (OutputStream) Matchers.anyObject(), Matchers.anyObject()) .thenThrow(new IOException()) .thenReturn(someValue); 

Note that you can use static imports for Mockito.doThrow and Matchers.* And switch to any(OutputStream.class) instead of (OutputStream) anyObject() and complete this:

 // doVerb syntax with static imports doThrow(new IOException()) .doNothing() .when(mapper).writeValue(any(OutputStream.class), anyObject()); 

See the Mockito Documentation for Stubber for a complete list of commands that you can link.

+15
Nov 20 '13 at 19:02
source share



All Articles