http://www.baeldung.com/mockito-annotations
1. Overview
In this tutorial, we’ll cover all the annotations in the Mockito library– @Mock, @Spy, @Captorand @InjectMocks.
2. Enable Mockito Annotations
First – let’s see how to enable the use of annotations with Mockito tests.
In order for these annotations to be enabled, we’ll need to annotate the JUnit test with a runner– MockitoJUnitRunneras in the following example:
@RunWith(MockitoJUnitRunner.class)
public class MockitoAnnotationTest {
...
}
Alternatively we can enable these annotations programmaticallyas well, by invoking MockitoAnnotations.initMocks()as in the following example:
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
3. @MockAnnotation
The most used widely used annotation in Mockito is @Mock. We can use @Mockto create and inject mocked instances without having to call Mockito.mockmanually.
In the following example – we’ll create a mocked ArrayListwith the manual way without using @Mockannotation:
@Test public void whenNotUseMockAnnotation_thenCorrect() { List mockList = Mockito.mock(ArrayList.class); mockList.add("one"); Mockito.verify(mockList).add("one"); assertEquals(0, mockList.size()); Mockito.when(mockList.size()).thenReturn(100); assertEquals(100, mockList.size()); }
And now we’ll do the same but we’ll inject the mock using the @Mockannotation:
@Mock
List<String> mockedList;
@Test
public void whenUseMockAnnotation_thenMockIsInjected() {
mockedList.add("one");
Mockito.verify(mockedList).add("one");
assertEquals(0, mockedList.size());
Mockito.when(mockedList.size()).thenReturn(100);
assertEquals(100, mockedList.size());
}
Note how – in both examples, we’re interacting with the mock and verifying some of these interactions – just to make sure that the mock is behaving correctly.
4. @SpyAnnotation
Now – let’s see how to use @Spyannotation to spy on an existing instance.
In the following example – we create a spy of a Listwith the old way without using @Spyannotation:
@Test public void whenNotUseSpyAnnotation_thenCorrect() { List<String> spyList = Mockito.spy(new ArrayList<String>()); spyList.add("one"); spyList.add("two"); Mockito.verify(spyList).add("one"); Mockito.verify(spyList).add("two"); assertEquals(2, spyList.size()); Mockito.doReturn(100).when(spyList).size(); assertEquals(100, spyList.size()); }
Let’s now do the same – spy on the list – but do so using the @Spyannotation:
@Spy List<String> spiedList = new ArrayList<String>(); @Test public void whenUseSpyAnnotation_thenSpyIsInjected() { spiedList.add("one"); spiedList.add("two"); Mockito.verify(spiedList).add("one"); Mockito.verify(spiedList).add("two"); assertEquals(2, spiedList.size()); Mockito.doReturn(100).when(spiedList).size(); assertEquals(100, spiedList.size()); }
Note how, as before – we’re interacting with the spy here to make sure that it behaves correctly. In this example we:
- Used the realmethod spiedList.add()to add elements to the spiedList.
- Stubbedthe method spiedList.size()to return 100instead of 2using Mockito.doReturn().
5. @CaptorAnnotation
Next – let’s see how to use the @Captorannotation to create an ArgumentCaptorinstance.
In the following example – we create an ArgumentCaptorwith the old way without using @Captorannotation:
@Test public void whenNotUseCaptorAnnotation_thenCorrect() { List mockList = Mockito.mock(List.class); ArgumentCaptor<String> arg = ArgumentCaptor.forClass(String.class); mockList.add("one"); Mockito.verify(mockList).add(arg.capture()); assertEquals("one", arg.getValue()); }
Let’s now make use of @Captor for the same purpose – to create an ArgumentCaptorinstance:
@Mock
List mockedList;
@Captor
ArgumentCaptor argCaptor;
@Test
public void whenUseCaptorAnnotation_thenTheSam() {
mockedList.add("one");
Mockito.verify(mockedList).add(argCaptor.capture());
assertEquals("one", argCaptor.getValue());
}
Notice how the test becomes simpler and more readable when we take out the configuration logic.
6. @InjectMocksAnnotation
Now – let’s discuss how to use @InjectMocksannotation – to inject mock fields into the tested object automatically.
In the following example – we use @InjectMocksto inject the mock wordMapinto the MyDictionary dic:
@Mock
Map<String, String> wordMap;
@InjectMocks
MyDictionary dic = new MyDictionary();
@Test
public void whenUseInjectMocksAnnotation_thenCorrect() {
Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning");
assertEquals("aMeaning", dic.getMeaning("aWord"));
}
And here is the class MyDictionary:
public class MyDictionary {
Map<String, String> wordMap;
public MyDictionary() {
wordMap = new HashMap<String, String>();
}
public void add(final String word, final String meaning) {
wordMap.put(word, meaning);
}
public String getMeaning(final String word) {
return wordMap.get(word);
}
}
7. Notes
Finally – here is some notes about Mockito annotations:
- Use annotation to minimize repetitive mock creation code
- Use annotation to make the test more readable
- Use @InjectMocksto inject both @Spyand @Mockinstances