OverviewIn this tutorial, we'll
illustrate the various uses of the standard static mock methods of the Mockito API.
As in other articles focused on the Mockito framework (
like Mockito Verify or Mockito When/Then), the MyList class shown below will be used as the collaborator to be mocked in test cases:
- package mockito.prac.p3;
-
- import java.util.AbstractList;
-
- public class MyList extends AbstractList<String>{
- @Override
- public String get(int index) {
- return null;
- }
-
- @Override
- public int size() {
- return 1;
- }
- }
Simple MockingThe simplest overloaded variant of the mock method is the one with a single parameter for the class to be mocked:
- public static <T> T mock(Class<T> classToMock)
We'll use this method to mock a class and set an expectation:
- MyList listMock = Mockito.mock(MyList.class);
- when(listMock.add(anyString())).thenReturn(false);
Then we'll execute a method on the mock:
- boolean added = listMock.add("abc");
The following code confirms that we invoked the
add method on the mock. The invocation returns a value that matches the expectation we set before:
- verify(listMock).add(anyString());
- assertEquals(added, false);
Mocking With Mock's NameIn this section, we'll cover another variant of the mock method, which is provided with an argument specifying the name of the mock:
- public static <T> T mock(Class<T> classToMock, String name)
Generally speaking, the name of a mock has nothing to do with the working code. However, it may be
helpful in debugging, as we use the mock's name to track down verification errors. To ensure the exception message thrown from an unsuccessful verification includes the provided name of a mock, we'll use
assertThatThrownBy.
In the following code, we'll create a mock for the
MyList class and name it
myMock:
- MyList listMock = Mockito.mock(MyList.class, "myMock");
Then we'll set an expectation on a method of the mock and execute it:
- when(listMock.add(anyString())).thenReturn(false);
- listMock.add("abc");
Next, we'll call the verification inside the
assertThrows and verify the instance of the exception thrown:
- assertThrows(
- TooFewActualInvocations.class,
- () -> verify(listMock, times(2)).add(anyString()));
Further, we can also
verify the exception's message that it should contain the information about the mock:
- TooFewActualInvocations exception = assertThrows(
- TooFewActualInvocations.class,
- () -> verify(listMock, times(2)).add(anyString()));
- assertTrue(exception.getMessage().contains("myMock.add"));
Mocking With AnswerHere we'll demonstrate the use of a mock variant in which we'll configure the strategy for the mock's answers to interaction at creation time. This
mock method's signature in the Mockito documentation looks like the following:
- public static <T> T mock(Class<T> classToMock, Answer defaultAnswer)
Let's start with the definition of an implementation of the
Answer interface:
- static class CustomAnswer implements Answer<Boolean> {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- return false;
- }
- }
We'll use the
CustomAnswer class above for the generation of a mock:
- MyList listMock = Mockito.mock(MyList.class, new CustomAnswer());
If we don't set an expectation on a method, the default answer, configured by the CustomAnswer type, will come into play. In order to prove this, we'll skip over the expectation setting step and jump to the method execution:
- boolean added = listMock.add("abc");
The following verification and assertion confirm that the mock method with an
Answer argument worked as expected:
- verify(listMock).add(anyString());
- assertFalse(added);
Mocking With MockSettingsThe final mock method we'll cover in this article is the variant with a parameter of the
MockSettings type. We use this overloaded method to provide a non-standard mock.
There are several custom settings supported by methods of the
MockSettings interface, such as registering a listener for method invocations on the current mock with
invocationListeners, configuring serialization with
serializable, specifying the instance to spy on with
spiedInstance, configuring Mockito to attempt to use a constructor when instantiating a mock with
useConstructor, etc.
For convenience, we'll reuse the
CustomAnswer class introduced in the previous section to create a
MockSettings implementation that defines a default answer.
A MockSettings object is instantiated by a factory method:- MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());
We'll use that setting object in the creation of a new mock:
- MyList listMock = Mockito.mock(MyList.class, customSettings);
Similar to the preceding section, we'll invoke the
add method of a
MyList instance, and verify that the mock method with a
MockSettings argument works as expected:
- boolean added = listMock.add("abc");
-
- verify(listMock).add(anyString());
- assertFalse(added);
Complete Source CodeThe full unit test is as below:
- package mockito.prac.p3;
-
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertThrows;
- import static org.junit.Assert.assertTrue;
- import static org.mockito.ArgumentMatchers.anyString;
- import static org.mockito.Mockito.times;
- import static org.mockito.Mockito.verify;
- import static org.mockito.Mockito.when;
- import static org.mockito.Mockito.withSettings;
-
- import org.junit.jupiter.api.Test;
- import org.mockito.MockSettings;
- import org.mockito.Mockito;
- import org.mockito.exceptions.verification.TooFewActualInvocations;
- import org.mockito.invocation.InvocationOnMock;
- import org.mockito.stubbing.Answer;
-
- class UsingMockMethod {
-
- @Test
- void testSimpleMocking() {
- MyList listMock = Mockito.mock(MyList.class);
- when(listMock.add(anyString())).thenReturn(false);
-
- boolean added = listMock.add("abc");
-
- verify(listMock).add(anyString());
- assertEquals(added, false);
- }
-
- @Test
- void testMockingWithMockName() {
- MyList listMock = Mockito.mock(MyList.class, "myMock");
- when(listMock.add(anyString())).thenReturn(false);
-
- listMock.add("abc");
-
- TooFewActualInvocations exception = assertThrows(
- TooFewActualInvocations.class,
- () -> verify(listMock, times(2)).add(anyString()));
- assertTrue(exception.getMessage().contains("myMock.add"));
- }
-
- static class CustomAnswer implements Answer<Boolean> {
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- return false;
- }
- }
-
- @Test
- void testMockingWithAnswer() {
- MyList listMock = Mockito.mock(MyList.class, new CustomAnswer());
-
- boolean added = listMock.add("abc");
-
- verify(listMock).add(anyString());
- assertFalse(added);
- }
-
- @Test
- void testMockingWithMockSettings() {
- MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());
- MyList listMock = Mockito.mock(MyList.class, customSettings);
-
- boolean added = listMock.add("abc");
-
- verify(listMock).add(anyString());
- assertFalse(added);
- }
- }