美文网首页
@ExtendWith详细说明

@ExtendWith详细说明

作者: flyjar | 来源:发表于2025-08-05 11:22 被阅读0次

@ExtendWith 是 JUnit 5 中用于扩展测试框架功能的核心注解,它替代了 JUnit 4 中的 @RunWith 注解,提供了更灵活、更强大的扩展机制。通过 @ExtendWith,可以在测试生命周期的不同阶段插入自定义逻辑,实现诸如依赖注入、测试前置条件验证、异常处理等功能。

核心作用

@ExtendWith 的主要作用是注册一个或多个扩展类(Extension),这些扩展类可以干预测试的执行流程。JUnit 5 的扩展模型基于事件驱动,允许扩展类在测试生命周期的关键节点(如测试类初始化、测试方法执行前后等)执行自定义逻辑。

使用方式

1. 基本语法

// 单个扩展
@ExtendWith(MyExtension.class)
class MyTest { ... }

// 多个扩展(数组形式)
@ExtendWith({ExtensionA.class, ExtensionB.class})
class MyTest { ... }
  • 可以标注在测试类测试方法上。
  • 若标注在类上,该扩展对类中所有测试方法生效;若标注在方法上,仅对该方法生效。

2. 常见内置扩展

JUnit 5 及第三方库(如 Spring、Mockito)提供了许多现成的扩展,例如:

  • MockitoExtension:由 Mockito 提供,用于简化 Mock 对象的创建和注入。

    @ExtendWith(MockitoExtension.class)
    class UserServiceTest {
        @Mock // 自动创建 Mock 对象
        private UserRepository userRepo;
        
        @InjectMocks // 自动注入依赖
        private UserService userService;
    }
    
  • SpringExtension:由 Spring 提供,用于集成 Spring 容器,支持 @Autowired 等注解。

    @ExtendWith(SpringExtension.class)
    @ContextConfiguration(classes = AppConfig.class)
    class SpringIntegrationTest {
        @Autowired
        private UserService userService;
    }
    
  • ParameterResolver 相关扩展:用于解析测试方法的参数(如 @TestInfo@TestReporter 等内置参数)。

自定义扩展

若内置扩展无法满足需求,可以通过实现 JUnit 5 提供的扩展接口来自定义扩展。常用的扩展接口包括:

接口 作用场景
BeforeAllCallback @BeforeAll 执行前触发
AfterAllCallback @AfterAll 执行后触发
BeforeEachCallback @BeforeEach 执行前触发
AfterEachCallback @AfterEach 执行后触发
BeforeTestExecutionCallback 在测试方法执行前触发(@BeforeEach 之后)
AfterTestExecutionCallback 在测试方法执行后触发(@AfterEach 之前)
ParameterResolver 解析测试方法的参数(如自定义参数注入)
TestExecutionExceptionHandler 处理测试方法抛出的异常

自定义扩展示例:计时扩展

下面是一个简单的扩展,用于记录测试方法的执行时间:

import org.junit.jupiter.api.extension.*;
import java.time.Duration;
import java.time.Instant;

// 实现测试执行前后的回调接口
public class TimingExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

    private Instant start;

    // 测试方法执行前记录开始时间
    @Override
    public void beforeTestExecution(ExtensionContext context) {
        start = Instant.now();
    }

    // 测试方法执行后计算并打印耗时
    @Override
    public void afterTestExecution(ExtensionContext context) {
        Duration duration = Duration.between(start, Instant.now());
        String testName = context.getDisplayName(); // 获取测试方法名称
        System.out.printf("测试 [%s] 执行耗时: %d 毫秒%n", testName, duration.toMillis());
    }
}

使用自定义扩展:

@ExtendWith(TimingExtension.class) // 注册计时扩展
class MyTest {
    @Test
    void testMethod1() throws InterruptedException {
        Thread.sleep(100); // 模拟耗时操作
    }

    @Test
    void testMethod2() throws InterruptedException {
        Thread.sleep(200);
    }
}

执行结果:

测试 [testMethod1] 执行耗时: 102 毫秒
测试 [testMethod2] 执行耗时: 201 毫秒

与 JUnit 4 @RunWith 的区别

  • 灵活性@ExtendWith 支持同时注册多个扩展(数组形式),而 @RunWith 只能指定一个运行器(Runner)。
  • 扩展性:JUnit 5 的扩展模型基于多个细粒度接口,扩展类可按需实现特定接口;而 JUnit 4 的 Runner 需重写大量方法,耦合度较高。
  • 兼容性@ExtendWith 可以嵌套使用(结合 @Nested 注解),而 @RunWith 不支持嵌套测试类。

总结

@ExtendWith 是 JUnit 5 扩展机制的入口,通过它可以:

  1. 集成第三方框架(如 Spring、Mockito)。
  2. 自定义测试行为(如计时、日志、权限验证等)。
  3. 灵活控制测试生命周期,实现复杂的测试场景。

掌握 @ExtendWith 的使用和扩展原理,能极大提升 JUnit 5 测试的灵活性和可维护性。

相关文章

  • Junit5介绍

    1. ExtendWith注解 所属包为org.junit.jupiter.api.extension,@Exte...

  • Java – 理解 @ExtendWith(SpringExte

    在JUnit5之前,我们用@RunWith(MockitoJUnitRunner.class)注解,使用Mocki...

  • maven配置

    文件架构 详细说明

  • day 15【操作系统文件属性】

    一.文件属性详细说明----文件的权限说明 文件数据权限有什么: 二.文件属性详细说明-----文件得用户信息 系...

  • 项目详细说明

    问:为什么这个项目需要redux: 做项目的时候我通过不停总结,总算想通了:每次在页面发生跳转的时候,为了确保在下...

  • NSURLSessionConfiguration详细说明

    NSURLSessionConfiguration类的说明 NSURLSession 的配置选项。当一个会话被创建...

  • ClientSdk详细说明

    数据库相关 ClientDbExecute ClientDbQuery 配置相关 ClientGetConfigs...

  • Plist详细说明

    1. Application does not run in background(鍵名:UIApplicatio...

  • javadoc详细说明

    先看结果 本人用过idea生成的,方法如下: 1.先在idea 配置注释 菜单栏File->settings-> ...

  • Vagrantfile详细说明

    Vagrant文件说明 [x] Vagrantfile里定义的路径,都是以Vagrantfile文件所在目录,为工...

网友评论

      本文标题:@ExtendWith详细说明

      本文链接:https://www.haomeiwen.com/subject/cufdojtx.html