编写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注解添加两个关键元注解:
@Retention(RetentionPolicy.RUNTIME):确保注解在运行时可被反射读取@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
相关产品推荐
相关产品推荐

