1. Overview
In this tutorial, we're going to look at different ways to create mock objects using Mockito. Mockito provides specific annotations to automatically create mocks. Additionally, we can use factory methods to manually create mock objects.
2. Annotation Based Mock Creation
Firstly, Mockito provides the @Mock annotation to define mock objects. After defining mocks, we must inject those mocks into a real object. For this purpose, Mockito gives us @InjectMocks annotation.
However, putting the @Mock annotation on a property doesn't automatically create a mock object. Similarly, annotating a property with @InjectMocks doesn't bind mocks into it. Because these annotations must be processed by some mechanism.
2.1. Using MockitoJUnitRunner
The MockitoJUnitRunner class is the primary way to initialize mocks with the help of annotations.
We must use MockitoJUnitRunner with the @RunWith annotation:
@RunWith(MockitoJUnitRunner.class)
public class MockitoRunnerInitializeTest {
@InjectMocks
private PersonService personService;
@Mock
private PersonRepository personRepository;
@Test
public void shouldSavePerson() {
Person person = new Person("test");
personService.save(person);
Mockito.verify(personRepository).save(person);
}
}
Here, the personRepository field has the @Mock annotation so Mockito creates a mock object for it. Mockito then injects this mock into the personService instance, since it has the @InjectMocks annotation.
2.2. Using MockitoRule
MockitoRule is another way to process Mockito annotations and create mock objects:
public class WithMockitoRuleTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@InjectMocks
private PersonService personService;
@Mock
private PersonRepository personRepository;
@Test
public void shouldSavePerson() {
Person person = new Person("test");
personService.save(person);
Mockito.verify(personRepository).save(person);
}
}
Here, we're creating a MockitoRule instance - MockitoJUnit.rule(), then we're annotating it with @Rule. This will have the same effect as the previous example where we used MockitoJUnitRunner.
2.3. Using MockitoAnnotations
Next, we'll use MockitoAnnotations to initialize mock objects. It'll scan the properties annotated with @Mock and then will initialize them:
public class MockitoAnnotationsInitializeTest {
@InjectMocks
private PersonService personService;
@Mock
private PersonRepository personRepository;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldSavePerson() {
Person person = new Person("test");
personService.save(person);
Mockito.verify(personRepository).save(person);
}
}
Here, we're calling MockitoAnnotations.initMocks(this) to initialize mocks. Note that, we're calling it in the @Before method to take effect immediately and to not clutter the test logic.
3. Manual Mock Creation
Now let's look at how we can create mock objects manually.
Until now we've used the @Mock annotation, but it isn't mandatory. We'll next use Mockito.mock() to create our mocks. In this approach, we must also compose different mock objects with the real object manually:
public class MockitoManualTest {
private PersonService personService;
private PersonRepository personRepository;
@Before
public void setUp() {
personRepository = Mockito.mock(PersonRepository.class);
personService = new PersonService(personRepository);
}
@Test
public void shouldSavePerson() {
Person person = new Person("test");
personService.save(person);
Mockito.verify(personRepository).save(person);
}
}
Here, we're creating a mock for PersonRepository via Mockito.mock(PersonRepository.class). Also, notice that we're creating PersonService manually and passing the PersonRepository mock into its constructor.
4. Summary
In this tutorial, we explored different ways to initialize mock objects using Mockito.
Check out the source code for all examples over on Github.