一、常用扩展概览
JUnit 5 提供了丰富的扩展机制,以下是一些常用的扩展及其作用:
扩展名称 | 核心功能 |
---|---|
MockitoExtension | 集成 Mockito 框架,支持依赖注入和 Mock 对象管理。 |
SpringExtension | 集成 Spring 框架,支持 Spring 上下文加载和依赖注入。 |
TempDirectory | 自动创建和清理临时目录。 |
ConditionalExecution | 根据条件动态跳过或执行测试。 |
TimingExtension | 记录测试执行时间。 |
ParameterResolver | 自定义参数解析(依赖注入)。 |
TestWatcher | 监控测试执行状态(如成功、失败、跳过)。 |
二、常用扩展详细介绍
1. MockitoExtension
功能:集成 Mockito 框架,支持依赖注入和 Mock 对象管理。
使用场景:单元测试中需要 Mock 依赖对象时。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void testFindUserById() {
when(userRepository.findById(1L)).thenReturn(new User(1L, "Alice"));
User user = userService.findUserById(1L);
Assertions.assertEquals("Alice", user.getName());
}
}
2. SpringExtension
功能:集成 Spring 框架,支持 Spring 上下文加载和依赖注入。
使用场景:Spring 应用的集成测试。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {TestConfig.class})
class UserServiceSpringTest {
@Autowired
private UserService userService;
@Test
void testFindUserById() {
User user = userService.findUserById(1L);
Assertions.assertEquals("Alice", user.getName());
}
}
3. TempDirectory
功能:自动创建和清理临时目录。
使用场景:测试中需要临时文件或目录时。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.api.extension.ExtendWith;
import java.nio.file.Path;
@ExtendWith(TempDirectory.class)
class TempDirTest {
@Test
void testTempDir(@TempDir Path tempDir) {
Path file = tempDir.resolve("test.txt");
Assertions.assertFalse(Files.exists(file));
}
}
4. ConditionalExecution
功能:根据条件动态跳过或执行测试。
使用场景:根据环境变量、配置或运行时条件决定是否执行测试。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
@ExtendWith(ConditionalExecution.class)
class ConditionalTest {
@Test
@EnabledIfEnvironmentVariable(named = "ENV", matches = "CI")
void testOnlyInCI() {
Assertions.assertTrue(true);
}
}
5. TimingExtension
功能:记录测试执行时间。
使用场景:性能测试或监控测试耗时。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(TimingExtension.class)
class TimingTest {
@Test
void fastTest() throws InterruptedException {
Thread.sleep(100);
}
@Test
void slowTest() throws InterruptedException {
Thread.sleep(200);
}
}
6. ParameterResolver
功能:自定义参数解析(依赖注入)。
使用场景:测试方法需要动态注入参数时。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolver;
@ExtendWith(CustomParameterResolver.class)
class ParameterResolverTest {
@Test
void testWithCustomParameter(String input) {
Assertions.assertEquals("Hello", input);
}
}
class CustomParameterResolver implements ParameterResolver {
@Override
public boolean supportsParameter(ParameterContext paramCtx, ExtensionContext extCtx) {
return paramCtx.getParameter().getType() == String.class;
}
@Override
public Object resolveParameter(ParameterContext paramCtx, ExtensionContext extCtx) {
return "Hello";
}
}
7. TestWatcher
功能:监控测试执行状态(如成功、失败、跳过)。
使用场景:记录测试结果或执行额外逻辑(如发送通知)。
示例:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.TestWatcher;
import org.junit.jupiter.api.extension.ExtensionContext;
@ExtendWith(CustomTestWatcher.class)
class TestWatcherTest {
@Test
void successfulTest() {
Assertions.assertTrue(true);
}
@Test
void failedTest() {
Assertions.fail("故意失败");
}
}
class CustomTestWatcher implements TestWatcher {
@Override
public void testSuccessful(ExtensionContext context) {
System.out.println("测试成功: " + context.getDisplayName());
}
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
System.out.println("测试失败: " + context.getDisplayName());
}
}
三、组合使用扩展
多个扩展可以通过 @ExtendWith
组合使用:
@ExtendWith({MockitoExtension.class, TimingExtension.class})
class CombinedTest {
// ...
}
四、总结
常用扩展的作用:
- MockitoExtension:简化 Mock 对象管理。
- SpringExtension:集成 Spring 上下文。
- TempDirectory:管理临时文件。
- ConditionalExecution:动态控制测试执行。
- TimingExtension:监控测试耗时。
- ParameterResolver:自定义依赖注入。
- TestWatcher:监控测试状态。
推荐实践:
- 优先使用成熟的第三方扩展(如 Mockito、Spring 的扩展)。
- 在需要复用逻辑时开发自定义扩展。
- 通过组合扩展实现复杂测试需求。