You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拦截JUnit5中带有@Disabled注解的测试方法?

拦截JUnit5中@Disabled测试方法的解决方案

这个问题我之前也碰到过!确实,@Disabled标记的测试不会触发beforeTestExecution()这类执行阶段的回调——因为JUnit5会把它们直接标记为「跳过」,根本不会进入执行流程。不过有两种靠谱的方法可以拦截到这些禁用的测试,我给你详细说说:

方案1:使用DiscoveryListener(JUnit 5.7+版本适用)

如果你的JUnit5版本在5.7及以上,推荐用DiscoveryListener接口,它能在测试发现阶段就捕获到所有测试(包括禁用的),不用等到执行阶段。

实现示例

import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.engine.discovery.DiscoveryListener;
import org.junit.platform.engine.support.descriptor.MethodSource;
import org.junit.jupiter.api.Disabled;
import java.lang.reflect.Method;

public class DisabledTestTrackingExtension implements DiscoveryListener {

    @Override
    public void testFound(TestDescriptor testDescriptor) {
        // 只处理测试方法级别的描述符
        if (testDescriptor.getSource().isPresent() 
            && testDescriptor.getSource().get() instanceof MethodSource) {
            MethodSource methodSource = (MethodSource) testDescriptor.getSource().get();
            Method testMethod = methodSource.getJavaMethod().orElse(null);
            
            if (testMethod != null && testMethod.isAnnotationPresent(Disabled.class)) {
                // 这里写你要执行的操作,比如日志记录、统计等
                System.out.println("发现禁用的测试方法: " + testMethod.getName());
            }
        }
    }

    // 其他默认方法保持空实现即可,不需要额外重写
}

注册方式

  • 局部注册:在需要监听的测试类上添加@ExtendWith(DisabledTestTrackingExtension.class)
  • 全局注册:在src/test/resources/junit-platform.properties中添加配置:
    junit.platform.discovery.listeners=com.yourpackage.DisabledTestTrackingExtension
    

方案2:使用TestExecutionListener(兼容更早JUnit5版本)

如果你还在使用5.7以下的版本,可以用TestExecutionListener的testSkipped()方法——所有被跳过的测试(包括@Disabled标记的)都会触发这个回调。

实现示例

import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.engine.support.descriptor.MethodSource;
import org.junit.jupiter.api.Disabled;
import java.lang.reflect.Method;
import java.util.Optional;

public class DisabledTestTrackingListener implements TestExecutionListener {

    @Override
    public void testSkipped(TestIdentifier testIdentifier, Throwable throwable) {
        // 提取测试方法的反射对象
        Optional<Method> testMethod = testIdentifier.getSource()
                .filter(source -> source instanceof MethodSource)
                .map(source -> (MethodSource) source)
                .flatMap(MethodSource::getJavaMethod);
        
        testMethod.ifPresent(method -> {
            if (method.isAnnotationPresent(Disabled.class)) {
                // 执行你的自定义操作
                System.out.println("检测到被跳过的禁用测试: " + method.getName());
            }
        });
    }

    // 其他方法可按需重写,默认空实现即可
}

注册方式

全局注册是最方便的,在src/test/resources/junit-platform.properties中添加:

junit.platform.launcher.listeners=com.yourpackage.DisabledTestTrackingListener

小提示

  • DiscoveryListener是在测试发现阶段触发,不管后续是否被其他条件过滤,都能捕捉到;而testSkipped()是在执行阶段触发,只有最终被跳过的测试才会触发。
  • 如果需要区分是@Disabled导致的跳过还是其他条件(比如@EnabledOnJre不满足),直接检查方法上的@Disabled注解是最准确的方式。

内容的提问来源于stack exchange,提问作者Liviu Carausu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:57:51