はい、私が知っている方法はありますが、余分なコードを書く必要があります。
まず、JUnit が TestRule を無視する理由は、インターフェイスで宣言されているため、静的 (および最終) であるためです。
この問題を克服するには、次のようなカスタム ランナーを作成する必要があります。
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
public final class MyRunner extends BlockJUnit4ClassRunner {
public MyRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected List<TestRule> getTestRules(Object target) {
List<TestRule> testRules = super.getTestRules(target);
testRules.addAll(getStaticFieldTestRules(target));
return testRules;
}
private List<TestRule> getStaticFieldTestRules(Object target) {
List<TestRule> testRules = new ArrayList<>();
Class<?> clazz = target.getClass();
for (Field f : clazz.getFields()) {
if ((f.getModifiers() & Modifier.STATIC) != 0) {
if (f.isAnnotationPresent(Rule.class)) {
try {
testRules.add((TestRule) f.get(target));
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}
}
return testRules;
}
}
最後に、テストクラスに注釈を付けて、新しいカスタムランナーで実行すると、すべてが期待どおりになります...
import org.junit.runner.RunWith;
@RunWith(MyRunner.class)
public class Test implements IBaseTest {
@org.junit.Test
public void testName1() throws Exception {
}
@org.junit.Test
public void testName2() throws Exception {
}
}