Let's get started with a Microservice Architecture with Spring Cloud:
Mockito and JUnit 5 – Using ExtendWith
Last updated: October 29, 2017
1. Overview
In this quick tutorial, we’ll show how to integrate Mockito with the JUnit 5 extension model. To learn more about the JUnit 5 extension model, have a look at this article.
First, we’ll show how to create an extension that automatically creates mock objects for any class attribute or method parameter annotated with @Mock.
Then, we’ll use our Mockito extension in a JUnit 5 test class.
2. Maven Dependencies
Let’s add the JUnit 5 (jupiter) and mockito dependencies to our pom.xml:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
The latest versions of junit-jupiter-engine and mockito-core can be downloaded from Maven Central.
3. Mockito Extension
Mockito provides an implementation for JUnit5 extensions in the library – mockito-junit-jupiter.
We’ll include this dependency in our pom.xml:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
4. Building the Test Class
Let’s build our test class and attach the Mockito extension to it:
@ExtendWith(MockitoExtension.class)
class UserServiceUnitTest {
UserService userService;
// ...
}
We can use the @Mock annotation to inject a mock for an instance variable that we can use anywhere in the test class:
@Mock UserRepository userRepository;
Also, we can inject mock objects into method parameters:
@BeforeEach
void init(@Mock SettingRepository settingRepository) {
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
lenient().when(settingRepository.getUserMinAge()).thenReturn(10);
when(settingRepository.getUserNameMinLength()).thenReturn(4);
lenient().when(userRepository.isUsernameAlreadyExists(any(String.class)))
.thenReturn(false);
}
Please note the use of lenient() here. Mockito throws an UnsupportedStubbingException when an initialized mock is not called by one of the test methods during execution. We can avoid this strict stub checking by using this method when initializing the mocks.
We can even inject a mock object into a test method parameter:
@Test
void givenValidUser_whenSaveUser_thenSucceed(@Mock MailClient mailClient) {
// Given
user = new User("Jerry", 12);
when(userRepository.insert(any(User.class))).then(new Answer<User>() {
int sequence = 1;
@Override
public User answer(InvocationOnMock invocation) throws Throwable {
User user = (User) invocation.getArgument(0);
user.setId(sequence++);
return user;
}
});
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
// When
User insertedUser = userService.register(user);
// Then
verify(userRepository).insert(user);
assertNotNull(user.getId());
verify(mailClient).sendUserRegistrationMail(insertedUser);
}
Note that the MailClient mock we inject as a test parameter will NOT be the same instance we injected in the init method.
5. Conclusion
Junit 5 has provided a nice model for the extension. We demonstrated a simple Mockito extension that simplified our mock creation logic.
The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.















