@extendwith 是 junit 5 中声明式注册扩展的核心注解,支持在测试类或方法上复用外部行为(如 mock 管理、spring 集成、日志增强等),通过实现 extension 接口并按序调用生命周期方法实现可插拔能力。

@ExtendWith 是 JUnit 5 中用于声明式注册扩展(Extension)的核心注解,它让测试类或单个测试方法能复用外部行为(比如资源初始化、Mock 管理、事务控制、日志增强等),而无需侵入业务逻辑代码。
一、基础用法:加载自定义或内置扩展
只需在测试类或方法上添加 @ExtendWith,传入一个或多个实现了 Extension 接口的类:
@ExtendWith(MockitoExtension.class) // 启用 Mockito 支持
@ExtendWith(DatabaseCleanupExtension.class) // 自定义清理扩展
class UserServiceTest {
@Test
void shouldCreateUser() {
// 测试逻辑
}
}
JUnit 5 会按顺序创建并调用这些扩展的生命周期方法(如 beforeEach、afterEach、beforeAll 等)。
二、常用内置扩展示例
JUnit 5 提供了多个开箱即用的扩展,直接使用即可:
-
@ExtendWith(MockitoExtension.class):自动注入
@Mock、@Spy、@InjectMocks字段,替代手动MockitoAnnotations.initMocks(this) -
@ExtendWith(SpringExtension.class):配合
@ContextConfiguration或@SpringBootTest,让测试运行在 Spring 容器中(注意:Spring Boot 2.2+ 默认已自动注册,通常无需显式写) - @ExtendWith(DisableOnCIExtension.class)(需自定义):可封装条件逻辑,例如跳过 CI 环境中的慢测试
三、快速编写一个实用自定义扩展
比如实现一个“测试执行前后打印日志”的简单扩展:
public class LoggingExtension implements TestWatcher, BeforeEachCallback, AfterEachCallback {
@Override
public void beforeEach(ExtensionContext context) {
System.out.println("▶️ 开始测试: " + context.getDisplayName());
}
@Override
public void afterEach(ExtensionContext context) {
System.out.println("⏹️ 结束测试: " + context.getDisplayName());
}
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
System.err.println("❌ 失败: " + cause.getMessage());
}
}
然后在测试中启用:@ExtendWith(LoggingExtension.class)
四、注意事项与技巧
- 多个 @ExtendWith 可叠加,但顺序会影响执行次序(先声明的先初始化)
- 扩展类必须有无参构造函数;若需依赖注入(如 Spring Bean),应改用
@RegisterExtension字段方式 - 想对单个测试方法生效?把 @ExtendWith 写在
@Test方法上即可(作用范围更细) - 避免在扩展中做耗时操作(如连接数据库),否则拖慢整个测试套件
掌握 @ExtendWith 就等于掌握了 JUnit 5 的可插拔能力核心。它不复杂但容易忽略——很多重复模板代码,其实一条注解就能解耦。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











