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

编写JUnit Rule时,无法通过Description获取自定义RetryCount注解

解决JUnit Rule无法获取自定义@RetryCount注解的问题

这个问题的核心原因很直白:你的自定义@RetryCount注解缺少必要的元注解配置,导致JUnit在运行时无法通过反射获取到它。

问题根源

Java注解默认的@Retention策略是RetentionPolicy.CLASS——这意味着注解仅在编译阶段保留,编译后的class文件里虽然存有注解信息,但运行时反射无法读取到它。而JUnit的Description是通过运行时反射来获取方法注解的,自然拿不到你的@RetryCount。

你提到@Deprecated能正常获取,那是因为@Deprecated本身的元注解就做了正确配置:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

它明确指定了运行时可见的Retention策略,所以能被反射顺利读取。

解决方案

只需要给你的@RetryCount注解添加两个关键元注解:

  1. @Retention(RetentionPolicy.RUNTIME):确保注解在运行时可被反射读取
  2. @Target(ElementType.METHOD):明确注解只能用在方法上(匹配你的使用场景)

修改后的完整Rule代码如下:

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class Retry implements TestRule {
    private int retryCount = 10;

    @Override
    public Statement apply(Statement base, Description description) {
        return new Statement() {
            public void evaluate() throws Throwable {
                RetryCount annotation = description.getAnnotation(RetryCount.class);
                int retries = (annotation != null) ? annotation.retries() : retryCount;

                AssertionError lastFailure = null;
                for (int i = 0; i < retries; i++) {
                    try {
                        base.evaluate();
                        return;
                    } catch (AssertionError err) {
                        lastFailure = err;
                    }
                }
                throw new AssertionError("Gave up after " + retries + " tries", lastFailure);
            }
        };
    }

    // 修正后的自定义注解,添加必要元注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public static @interface RetryCount {
        int retries() default 1;
    }
}

额外优化(可选)

如果需要给整个测试类统一设置重试次数,只需扩展@Target的参数范围:

@Target({ElementType.METHOD, ElementType.TYPE})

这样你既可以在单个测试方法上标注@RetryCount,也可以在测试类上标注,实现类级别的重试配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:49:53