1. Overview
In this short tutorial, we focus on mocking void methods with Mockito.
As with other articles focused on the Mockito framework (like Mockito Verify, Mockito When/Then, and Mockito’s Mock Methods) the MyList class shown below will be used as the collaborator in test cases. We’ll add a new method for this tutorial:
public class MyList extends AbstractList<String> { @Override public void add(int index, String element) { // no-op } }
2. Simple Mocking and Verifying
Void methods can be used with Mockito’s doNothing(), doThrow(), and doAnswer() methods, making mocking and verifying intuitive:
@Test public void whenAddCalledVerfied() { MyList myList = mock(MyList.class); doNothing().when(myList).add(isA(Integer.class), isA(String.class)); myList.add(0, ""); verify(myList, times(1)).add(0, ""); }
However, doNothing() is Mockito’s default behavior for void methods.
This version of whenAddCalledVerified() accomplishes the same thing as the one above:
@Test public void whenAddCalledVerfied() { MyList myList = mock(MyList.class); myList(0, ""); verify(myList, times(1)).add(0, ""); }
DoThrow() generates an exception:
@Test(expected = Exception.class) public void givenNull_AddThrows() { MyList myList = mock(MyList.class); doThrow().when(myList).add(isA(Integer.class), isNull()); myList.add(0, null); }
We’ll cover doAnswer() below.
3. Argument Capture
One reason to override the default behavior with doNothing() is to capture arguments.
In the example above verify() is used to check the arguments passed to add().
However, we may need to capture the arguments and do something more with them. In these cases, we use doNothing() just as we did above, but with an ArgumentCaptor:
@Test public void whenAddCalledValueCaptured() { MyList myList = mock(MyList.class); ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class); doNothing().when(myList).add(any(Integer.class), valueCapture.capture()); myList.add(0, "captured"); assertEquals("captured", valueCapture.getValue()); }
4. Answering a Call to Void
A method may perform more complex behavior than merely adding or setting value. For these situations we can use Mockito’s Answer to add the behavior we need:
@Test public void whenAddCalledAnswered() { MyList myList = mock(MyList.class); doAnswer((Answer) invocation -> { Object arg0 = invocation.getArgument(0); Object arg1 = invocation.getArgument(1); assertEquals(3, arg0); assertEquals("answer me", arg1); return null; }).when(myList).add(any(Integer.class), any(String.class)); myList.add(3, "answer me"); }
As explained in Mockito’s Java 8 Features we use a lambda with Answer to define custom behavior for add().
5. Partial Mocking
Partial mocks are an option, too. Mockito’s doCallRealMethod() can be used for void methods:
@Test public void whenAddCalledRealMethodCalled() { MyList myList = mock(MyList.class); doCallRealMethod().when(myList).add(any(Integer.class), any(String.class)); myList.add(1, "real"); verify(myList, times(1)).add(1, "real"); }
This allows us to call the actual method is called and verify it at the same time.
6. Conclusion
In this brief tutorial, we covered four different ways to approach void methods when testing with Mockito.
As always, the examples are available in this GitHub project.