我正在尝试编写一个简单的JUnit Rule实现,如果不成功,它会在一定时间内重新运行测试用例。
它可以正常工作,但我想使用我附加到方法的自定义注释使每个方法可配置。
这是我的规则实施:
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);
// Problem is here, the annotation is always null!
int retries = (annotation != null) ? annotation.retries() : retryCount;
// keep track of the last failure to include it in our failure later
AssertionError lastFailure = null;
for (int i = 0; i < retries; i++) {
try {
// call wrapped statement and return if successful
base.evaluate();
return;
} catch (AssertionError err) {
lastFailure = err;
}
}
// give meaningful message and include last failure for the
// error trace
throw new AssertionError("Gave up after " + retries + " tries", lastFailure);
}
};
}
// the annotation for method-based retries
public static @interface RetryCount {
public int retries() default 1;
}
}
在我评论的行中,我没有得到附加到方法的注释:
public class UnreliableServiceUnitTest {
private UnreliableService sut = new UnreliableService();
@Rule
public Retry retry = new Retry();
@Test
@RetryCount(retries=5) // here it is
public void worksSometimes() {
boolean worked = sut.workSometimes();
assertThat(worked, is(true));
}
}
如果我调试规则,Description
注释列表包含@Test
注释,但不包含@RetryCount
。我还尝试添加@Deprecated
,这也将被添加。
知道为什么吗?
为完整起见,这是样本SUT:
public class UnreliableService {
private static Random RANDOM = new Random();
// needs at least two calls
private static int COUNTER = RANDOM.nextInt(8) + 2;
public boolean workSometimes() {
if (--COUNTER == 0) {
COUNTER = RANDOM.nextInt(8) + 2;
return true;
}
return false;
}
}
答案 0 :(得分:2)
@Test
注释是运行时注释。您的RetryCount
未定义为此类。它应该是这样你可以在运行时访问它。将您的代码更改为:
// the annotation for method-based retries
@Retention(value=RUNTIME)
public static @interface RetryCount {
public int retries() default 1;
}
使用RetentionPolicy Runtime可以反射性地阅读注释。见here the Javadoc