Mockito
Init
Enable Mockito annotations
- Call the method
MockitoAnnotations.initMocks(this)
to initialize annotated fields
- Use the built-in runner
@RunWith(MockitoJUnitRunner.class)
Mock
Default to return null value
// MyList listMock = mock(MyList.class, "myMock"); User user = Mockito.mock(User.class); when(user.getName()).thenReturn("John"); doReturn(true).when(user).getName());
//org.mockito.Mockito.mock(java.lang.Class<T>) //org.mockito.Mockito.mock(java.lang.Class<T>, java.lang.String) //org.mockito.Mockito.mock(java.lang.Class<T>, org.mockito.stubbing.Answer) //org.mockito.Mockito.mock(java.lang.Class<T>, org.mockito.MockSettings) //method 1 Foo foo1 = Mockito.mock(Foo.class); //method 2:define mock name Foo foo2 = Mockito.mock(Foo.class, "mock_1"); //method 3:mock logic Foo foo3 = Mockito.mock(Foo.class, new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { //define return value return null; } }); //method 4:use MockSettings configure mock Foo foo4 = Mockito.mock(Foo.class, Mockito.withSettings().defaultAnswer(Mockito.RETURNS_SMART_NULLS)); /* Mockito.withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS) Mockito.withSettings() .useConstructor("arg1", 123).defaultAnswer(CALLS_REAL_METHODS) InnerAbstract spy = mock(InnerAbstract.class, Mockito.withSettings().useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS)); */
Spy - to spy on an existing instance
Default to execute original methods
User user = Mockito.spy(new User()); when(user.getName()).thenReturn("John"); doReturn(true).when(user).getName());
//org.mockito.Mockito.spy(java.lang.Class<T>) //org.mockito.Mockito.spy(T) //method 1:spy a class List spy1 = Mockito.spy(List.class); //method 2:spy an object List spy2 = Mockito.spy(new ArrayList<>());
@ExtendWith(MockitoExtension.class) public class GreetingsTest { // ... }
Mock Inject
create and inject mocked instances
@ExtendWith(MockitoExtension.class) public class MockitoTest { //Inject it with attributes having @Mock annotations @InjectMocks private Foo foo; //will be used to inject to foo @Mock private Bar bar; @Test public void mockTest() { Mockito.when(bar.add(1, 2)).thenReturn(7); int result = foo.sum(1, 2); Assert.assertEquals(7, result); } }
Configure method to call the real method:
when(listMock.size()).thenCallRealMethod(); assertThat(listMock).hasSize(1);
MockException
// way two when(listMock.add(anyString())) .thenReturn(false) .thenThrow(IllegalStateException.class); // way one doThrow(NullPointerException.class).when(listMock).clear();
Invocation times
// Verify number of interactions verify(mockedList, times(1)).size(); // Verify no interaction with the whole mock verifyNoInteractions(mockedList); // Verify no interaction with a specific method verify(mockedList, times(0)).size(); //atLeast(1), atMost(1) verify(mockedList, never()).size(); // Verify order of interactions InOrder inOrder = Mockito.inOrder(mockedList); inOrder.verify(mockedList).size(); inOrder.verify(mockedList).add("a parameter"); inOrder.verify(mockedList).clear(); // Verify interaction with exact argument verify(mockedList).add("test"); verify(flowerService).analyze(or(eq("poppy"), endsWith("y")));
@Captor
@Mock List mockedList; @Captor ArgumentCaptor argCaptor; @Test public void whenUseCaptorAnnotation_thenTheSame() { mockedList.add("one"); Mockito.verify(mockedList).add(argCaptor.capture()); assertEquals("one", argCaptor.getValue()); }
anyInt() anyString()
DoThrow
@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); }
doNothing
@Test public void whenAddCalledValueCaptured() { 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()); }
Answering
@Test public void whenAddCalledAnswered() { 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"); }
Verify
has been called and call times
@Test public void verify_publicMethodReturnString() { verify(mockSample, never()).publicMethodReturnString(); mockSample.publicMethodReturnString(); verify(mockSample).publicMethodReturnString(); mockSample.publicMethodReturnString(); verify(mockSample, times(2)).publicMethodReturnString(); }
isA、anyXxx、eq
@Test public void verify_publicMethodCalculate() { verify(mockSample, never()).publicMethodCalculate(1, 2); verify(mockSample, never()).publicMethodCalculate(isA(int.class), isA(int.class)); verify(mockSample, never()).publicMethodCalculate(anyInt(), anyInt()); verify(mockSample, never()).publicMethodCalculate(eq(1), eq(2)); mockSample.publicMethodCalculate(1, 2); verify(mockSample).publicMethodCalculate(1, 2); verify(mockSample).publicMethodCalculate(isA(int.class), isA(int.class)); verify(mockSample).publicMethodCalculate(anyInt(), anyInt()); verify(mockSample).publicMethodCalculate(eq(1), eq(2)); verify(mockSample, never()).publicMethodCalculate(1, 1); verify(mockSample, never()).publicMethodCalculate(eq(1), eq(1)); }

The following table gives an overview of the most important annotations in JUnit 5 from the
org.junit.jupiter.api
package.Annotation | Description |
@Test | Identifies a method as a test method. |
@Disabled("reason") | Disables a test method with an option reason. |
@BeforeEach | Executed before each test. Used to prepare the test environment, e.g., initialize the fields in the test class, configure the environment, etc. |
@AfterEach | Executed after each test. Used to cleanup the test environment, e.g., delete temporary data, restore defaults, cleanup expensive memory structures. |
@DisplayName("<Name>") | <Name> that will be displayed by the test runner. In contrast to method names the name can contain spaces to improve readability. |
@RepeatedTest(<Number>) | Similar to @Test but repeats the test a <Number> of times |
@BeforeAll | Annotates a static method which is executed once, before the start of all tests. It is used to perform time intensive activities, for example, to connect to a database. Methods marked with this annotation need to be defined as static to work with JUnit. |
@AfterAll | Annotates a static method which is executed once, after all tests have been finished. It is used to perform clean-up activities, for example, to disconnect from a database. Methods annotated with this annotation need to be defined as static to work with JUnit. |
@TestFactory | Annotates a method which is a Factory for creating dynamic tests |
@Nested | Lets you nest inner test classes to group your tests and to have additional @BeforeEach and @AfterEach methods. |
@Tag("<TagName>") | Tags a test method, tests in JUnit 5 can be filtered by tag. E.g., run only tests tagged with "fast". |
@ExtendWith | Lets you register an Extension class that adds functionality to the tests |
Assert throw
assertThatThrownBy(() -> verify(listMock, times(2)).add(anyString())) .isInstanceOf(TooFewActualInvocations.class) .hasMessageContaining("myMock.add");