Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this short tutorial, we focus on mocking void methods with Mockito.

Further reading:

Mockito's Java 8 Features

Overview of Java 8 support in Mockito framework, including Streams and default interface methods

Mocking Exception Throwing using Mockito

Learn to configure a method call to throw an exception in Mockito.

As with other articles focused on the Mockito framework (such as 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 whenAddCalled_thenVerified() {
    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
void whenAddCalled_thenVerified() {
    MyList myList = mock(MyList.class);
    myList.add(0, "");
 
    verify(myList, times(1)).add(0, "");
}

doThrow() generates an exception:

@Test
void givenNull_whenAddCalled_thenThrowsException() {
    MyList myList = mock(MyList.class);
    
    assertThrows(Exception.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, we used the verify() method 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
void givenArgumentCaptor_whenAddCalled_thenValueCaptured() {
    MyList myList = mock(MyList.class);
    
    ArgumentCaptor<String> 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
void givenDoAnswer_whenAddCalled_thenAnswered() {
    MyList myList = mock(MyList.class);
    
    doAnswer(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
void givenDoCallRealMethod_whenAddCalled_thenRealMethodCalled() {
    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 way, we can call the actual method and verify it at the same time.

6. Conclusion

In this brief article, we covered four different ways to approach void methods when testing with Mockito.

As always, the examples are available in this GitHub project.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.