1. 概述
在这个快速教程中,我们将展示如何将Mockito与JUnit 5扩展模型集成。有关JUnit 5扩展模型的更多信息,请参阅这篇文章。
首先,我们将演示如何创建一个扩展,自动为任何带有@Mock注解的类属性或方法参数创建模拟对象。
然后,我们将在JUnit 5测试类中使用我们的Mockito扩展。
2. Maven依赖
让我们在pom.xml
中添加JUnit 5(jupiter)和mockito
依赖:
<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>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
4. 构建测试类
现在,让我们构建我们的测试类,并将其与Mockito扩展连接起来:
@ExtendWith(MockitoExtension.class)
class UserServiceUnitTest {
UserService userService;
// ...
}
我们可以使用@Mock注解为我们在测试类中任何地方都可以使用的实例变量注入模拟对象:
@Mock UserRepository userRepository;
同样,我们也可以将模拟对象注入到方法参数中:
@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);
}
请注意这里使用了lenient()
。当在执行期间,初始化的模拟对象没有被测试方法调用时,Mockito会抛出UnsupportedStubbingException
。通过在初始化模拟对象时使用此方法,我们可以避免这种严格的断言检查。
我们甚至可以将模拟对象注入到测试方法参数中:
@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);
}
注意,作为测试参数注入的MailClient
模拟对象将与我们在init
方法中注入的不是一个实例。
5. 总结
JUnit 5为扩展提供了良好的模型。我们展示了一个简单的Mockito扩展,简化了我们的模拟对象创建逻辑。
本文中所有使用的代码可以在我们的GitHub项目中找到。