Creating Mocks With Mockito

After we have finished this lesson, we:

  • Understand how we should create our mock objects.
  • Can verify interactions that happened between the system under test and a mock object.
  • Know how we can capture the actual method parameter of an invoked method.

Creating Mocks With Mockito

As we remember, we can create a dummy, a stub, or a mock by invoking the mock() method of the Mockito class.

Also, because the test doubles created with Mockito are not stateless, we have to create our test doubles before a test method is invoked. This means that we have to create them in a setup method that is annotated with the @Before annotation.

However, this time we don’t have to add any methods into the TestDoubles class because it is crystal clear that the mock() method creates a mock object.

After we have created our mock object in a setup method, the source code of our test class looks as follows:

 1import org.junit.Before;
 2
 3import static org.mockito.Mockito.mock;
 4
 5public class MockitoTest {
 6
 7    private TaskRepository repository;
 8
 9    @Before
10    public void createMock() {
11        repository = mock(TaskRepository.class);
12    }
13}

The system under test was described in the lesson: Creating Stubs With Mockito . Also, I have removed the unused methods from the TaskRepository interface because they were not relevant for this lesson.

Also, if you want to use Strict mocks, you should add a new factory method called strictMock() into the TestDoubles class and use that method instead of the mock() method. This approach has two benefits:

  • It helps you to reduce duplicate code because you don’t have to override the default answer every time when you create a new strict mock.
  • It helps you to clarify your intentions and reduce misunderstandings.

After you have added this method into the TestDoubles class, its source code looks as follows:

 1import org.mockito.invocation.InvocationOnMock;
 2import org.mockito.stubbing.Answer;
 3
 4import static org.mockito.Mockito.mock;
 5
 6public final class TestDoubles {
 7
 8    private TestDoubles() {}
 9
10    public static <T> T dummy(Class<T> dummyClass) {
11        return mock(dummyClass);
12    }
13
14    public static <T> T strictStub(Class<T> stubClass) {
15        return mock(stubClass, new Answer() {
16            @Override
17            public Object answer(InvocationOnMock i) throws Throwable {
18                throw new RuntimeException(
19					"SUT invoked an unexpected method of a stub"
20				);
21            }
22        });
23    }
24
25    public static <T> T stub(Class<T> stubClass) {
26        return mock(stubClass);
27    }
28
29    public static <T> T strictMock(Class<T> mockClass) {
30        return mock(mockClass, new Answer() {
31            @Override
32            public Object answer(InvocationOnMock i) throws Throwable {
33                throw new RuntimeException(
34					"SUT invoked an unexpected method of a mock"
35				);
36            }
37        });
38    }
39}

Let’s find out how we can verify interactions with Mockito.

Verifying Interactions With Mockito

The Mockito class provides three static methods which we can use for verifying interactions that happened between the system under test and our mock object. These methods are:

  • The verify() method verifies that a specific interaction happened between the system under test and our mock object. The Mockito class has two verify() methods which are used for different purposes and both of these methods return a reference to the verified mock object.
  • The verifyNoMoreInteractions() method fails the test if any of the mock objects given as method parameters has unverified interactions. In other words, this method checks if the mock objects have interactions that were not verified by invoking the verify() method. Even though this method can be useful in certain situations, we should not use this method in every test method.
  • The verifyZeroInteractions() method verifies that no interactions happened between the system under test and the mock objects given as method parameters.

Next we will find out how we can use these methods in our unit tests.

Verifying Method Invocations

The next five examples demonstrate how we can verify interactions that happened or did not happen between the system under test and our mock object.

Example 1: Method Was Invoked Once

If we want to verify that the system under test invoked a method of our mock object only one time, we have to follow these steps:

  1. Configure the verified mock by by invoking the verify() method of the Mockito class. When we invoke this method, we have to pass a mock object as a method parameter.
  2. Configure the invoked method by invoking it. If the invoked method has method parameters, we have to configure the expected method parameters when we configure the invoked method.

If we want to verify that the findById() method of the TaskRepository interface was invoked once and 1L was passed as a method parameter, we have to write a unit test that looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Mockito.mock;
 5import static org.mockito.Mockito.verify;
 6
 7public class MockitoTest {
 8
 9    private TaskRepository repository;
10
11    @Before
12    public void createMock() {
13        repository = mock(TaskRepository.class);
14    }
15
16    @Test
17    public void verifyWhenMethodWasCalledOnce() {
18        repository.findById(1L);
19
20        verify(repository).findById(1L);
21    }
22}

Example 2: Method Was Invoked X Times

If we want to verify that the system under test invoked a method of our mock object X times, we have to follow these steps:

  1. Invoke the verify() method of the Mockito class and pass the following objects as method parameters:
  2. The target mock object.
  3. A VerificationMode object that specifies how many times the method must be invoked by the system under test.
  4. Configure the invoked method by invoking it. If the invoked method has method parameters, we have to configure the expected method parameters when we configure the invoked method.

If we want to verify that the findById() method of the TaskRepository interface was invoked once and 1L was passed as a method parameter, we have to create the second method parameter by invoking the times() method of the Mockito class. When we invoke this method, we have to pass the number of expected method invocations (1) as a method parameter.

After we have written our unit test, its source code looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Mockito.mock;
 5import static org.mockito.Mockito.times;
 6import static org.mockito.Mockito.verify;
 7
 8public class MockitoTest {
 9
10    private TaskRepository repository;
11
12    @Before
13    public void createMock() {
14        repository = mock(TaskRepository.class);
15    }
16
17    @Test
18    public void verifyThatMethodWasCalledOnce() {
19        repository.findById(1L);
20
21        verify(repository, times(1)).findById(1L);
22    }
23}

The Mockito class provides a few other factory methods that can be used for creating new VerificationMode objects. The Mockito API documentation provides more information about these factory methods.

Additional Reading:

Example 3: Method Was Never Invoked

If we want to verify that a method of our mock object was not invoked by the system under test, we have to create the second method parameter that is passed to the verify() method of the Mockito class by invoking the never() method of the Mockito class.

If we want to ensure that the findById() method of the TaskRepository interface was never invoked by using the method parameter 1L, we have to write a unit test that looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Mockito.mock;
 5import static org.mockito.Mockito.never;
 6import static org.mockito.Mockito.verify;
 7
 8public class MockitoTest {
 9
10    private TaskRepository repository;
11
12    @Before
13    public void createMock() {
14        repository = mock(TaskRepository.class);
15    }
16
17    @Test
18    public void verifyThatMethodWasNotInvoked() {
19        verify(repository, never()).findById(1L);
20    }
21}

Example 4: There Are No Unverified Interactions

If we want to verify that our mock has no unverified interactions, we have to follow these steps:

  1. Specify the expected interactions.
  2. Invoke the verifyNoMoreInteractions() method of the Mockito class and pass the TaskRepository mock as a method parameter.

For example, if we want to verify that the system under test invoked the findById() method once by using the method parameter 1L and it didn’t invoke any other methods of the TaskRepository interface, we have to write a unit test that looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Mockito.mock;
 5import static org.mockito.Mockito.verify;
 6import static org.mockito.Mockito.verifyNoMoreInteractions;
 7
 8public class MockitoTest {
 9
10    private TaskRepository repository;
11
12    @Before
13    public void createMock() {
14        repository = mock(TaskRepository.class);
15    }
16
17	@Test
18    public void verifyThatNoOtherMethodsWereInvoked() {
19        repository.findById(1L);
20
21        verify(repository).findById(1L);
22        verifyNoMoreInteractions(repository);
23    }
24}

Example 5: There Were No Interactions Between the System Under Test and Our Mock

If we want to verify that the system under test did not invoke any methods of the TaskRepository interface, we have to invoke the verifyZeroInteractions() method of the Mockito class and pass the TaskRepository mock object as a method parameter.

After we have written our unit test, its source code looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Mockito.mock;
 5import static org.mockito.Mockito.verifyZeroInteractions;
 6
 7public class MockitoTest {
 8
 9    private TaskRepository repository;
10
11    @Before
12    public void createMock() {
13        repository = mock(TaskRepository.class);
14    }
15
16    @Test
17    public void verifyThatNoInteractionsHappenedBetweenSUTAndMock() {
18        verifyZeroInteractions(repository);
19    }
20}

Using Argument Matchers

As we remember, If we configure the expected method parameter of an invoked method by simply passing it to the invoked method, Mockito verifies it by using the equals() method. Even though this is fine for most situations, sometimes we need extra flexibility. When this happens, we can specify the expected method parameter by using an argument matcher that is passed to the invoked method as a method parameter.

The org.mockito.Matchers class provides factory methods that we can use for creating different argument matchers. Let’s take a look at two examples that demonstrate how argument matchers work.

First, if we want to ensure that the findById() method of the TaskRepository interface was invoked by using a method parameter that is equal to 1L, we have to create our argument matcher by using the eq() method of the Matchers class.

After we have configured the expected method parameter by using the created argument matcher, the source code of our test method looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Matchers.eq;
 5import static org.mockito.Mockito.mock;
 6import static org.mockito.Mockito.verify;
 7
 8public class MockitoTest {
 9
10    private TaskRepository repository;
11
12    @Before
13    public void createMock() {
14        repository = mock(TaskRepository.class);
15    }
16
17    @Test
18    public void verifyThatMethodWasInvokedByPassing1LAsMethodParameter() {
19        repository.findById(1L);
20
21        verify(repository).findById(eq(1L));
22    }
23}

Second, if we want to verify that the findById() method of the TaskRepository interface was invoked and a Long object was passed as a method parameter, we have to create our argument matcher by using the anyLong() method of the Matchers class.

After we have configured the expected method parameter by using the created argument matcher, the source code of our test method looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3
 4import static org.mockito.Matchers.anyLong;
 5import static org.mockito.Mockito.mock;
 6import static org.mockito.Mockito.verify;
 7
 8public class MockitoTest {
 9
10    private TaskRepository repository;
11
12    @Before
13    public void createMock() {
14        repository = mock(TaskRepository.class);
15    }
16
17    @Test
18    public void verifyThatMethodWasInvokedByPassingAnyLongAsMethodParameter() {
19        repository.findById(1L);
20
21        verify(repository).findById(anyLong());
22    }
23}
If the verified method has multiple method parameters and we want to use argument matchers, we have to provide all method parameters by using argument matchers.

Additional Reading:

Using an Argument Captor

If we want to write assertions for the actual method parameter, we cannot use the “standard” argument matchers provided by the Matchers class because we have to capture the actual method parameter before we can write assertions for it. We can capture the actual method parameter by using the ArgumentCaptor<T> class.

For example, if we want to verify that the actual method pararameter that was passed to the findById() method of the TaskRepository interface is equal to 1L, we have to follow these steps:

  1. Create an ArgumentCaptor<Long> object by invoking the static forClass() method of the ArgumentCaptor class. When we invoke this method, we have to pass a Class object that specifies the type of the captured parameter (Long.class) as a method parameter.
  2. Ensure that the findById() method of the TaskRepository interface was invoked once and configure the expected method parameter by invoking the capture() method of the ArgumentCaptor class.
  3. Get the actual method parameter by invoking the getValue() method of the ArgumentCaptor class.
  4. Ensure that the actual method parameter is equal to 1L

After we have finished these steps, the source code of our test method looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3import org.mockito.ArgumentCaptor;
 4
 5import static org.assertj.core.api.Assertions.assertThat;
 6import static org.mockito.Mockito.mock;
 7import static org.mockito.Mockito.verify;
 8
 9public class MockitoTest {
10
11    private TaskRepository repository;
12
13    @Before
14    public void createMock() {
15        repository = mock(TaskRepository.class);
16    }
17
18    @Test
19    public void verifyThatMethodWasInvokedByUsingArgumentCaptor() {
20        repository.findById(1L);
21
22        ArgumentCaptor<Long> argument = ArgumentCaptor.forClass(Long.class);
23        verify(repository).findById(argument.capture());
24
25        Long actualId = argument.getValue();
26        assertThat(actualId).isEqualByComparingTo(1L);
27    }
28}

We can now verify interactions that happened between the system under test and our mock object. Let’s put our new skills into practice.

Putting Theory Into Practice

Let’s use our new skills and write one unit test for the createCopyOf() method of the TaskService class. We have to write a unit test which ensures that the saved Task object contains the correct information.

Also, because the goal of this lesson is to teach us how we can verify interactions with Mockito, the other parts of this unit test have been implemented by unknown developer.

The createCopyOf() method of the TaskService class was described in the lesson: Creating Stubs With Mockito .

We can write our unit test by following these steps:

  1. Create a new ArgumentCaptor<Task> object.
  2. Ensure that the save() method of the TaskRepository interface was invoked once and capture the actual method parameter.
  3. Get the actual method parameter.
  4. Verify that the saved Task object contains the correct information.

After we have finished our unit test, the source code of our test method looks as follows:

 1import org.junit.Before;
 2import org.junit.Test;
 3import org.mockito.ArgumentCaptor;
 4import org.mockito.invocation.InvocationOnMock;
 5
 6import java.util.Optional;
 7
 8import static org.assertj.core.api.Assertions.assertThat;
 9import static org.mockito.BDDMockito.given;
10import static org.mockito.Matchers.isA;
11import static org.mockito.Mockito.mock;
12import static org.mockito.Mockito.verify;
13
14public class MockitoTaskServiceTest {
15
16    private final Long CREATOR_ID = 33L;
17    private final String CREATOR_USERNAME = "username";
18    private final Long SOURCE_TASK_ID = 99L;
19    private final String SOURCE_TASK_DESCRIPTION = "description";
20    private final String SOURCE_TASK_TITLE = "title";
21
22    private TaskRepository repository;
23    private TaskService service;
24
25    @Before
26    public void configureSystemUnderTest() {
27        repository = mock(TaskRepository.class);
28        service = new TaskService(repository);
29    }
30
31    @Test
32    public void createCopyOf_WhenSourceTaskIsFound_ShouldSaveNewTask() {
33        Task sourceTask = new TaskBuilder()
34                .withDescription(SOURCE_TASK_DESCRIPTION)
35                .withTitle(SOURCE_TASK_TITLE)
36                .build();
37
38        given(repository.findById(SOURCE_TASK_ID))
39				.willReturn(Optional.of(sourceTask));
40
41        LoggedInUser creator = new LoggedInUser(CREATOR_ID, CREATOR_USERNAME);
42        service.createCopyOf(SOURCE_TASK_ID, creator);
43
44        ArgumentCaptor<Task> taskArgument = ArgumentCaptor.forClass(Task.class);
45        verify(repository).save(taskArgument.capture());
46
47        Task created = taskArgument.getValue();
48        assertThat(created.getCreator().getUserId())
49				.isEqualByComparingTo(CREATOR_ID);
50        assertThat(created.getDescription())
51				.isEqualTo(SOURCE_TASK_DESCRIPTION);
52        assertThat(created.getTitle()).isEqualTo(SOURCE_TASK_TITLE);
53    }
54}

Let’s summarize what we learned from this lesson.

Summary

This lesson has taught us six things:

  • We have to create our mock object before a test method is invoked.
  • We should create our mock object by using the mock() method of the Mockito class.
  • We can verify interactions that happened between the system under test and a mock object by using the methods provided by the Mockito class.
  • By default, Mockito compares the expected method parameter with the actual method parameter by using the equals() method.
  • We can customize the method parameter verification process by using argument matchers.
  • If we need to get a reference to the actual method parameter, we have to use an argument captor.

Get the source code from Github