高级,我有一个非常简单的JUnit测试类。我有几个@Test和一个@Before,它做了一些设置。对于一个测试用例,设置会有所不同(我不希望它运行)。
从一些搜索中我发现https://stackoverflow.com/a/13017452/413254.这建议创建一个@Rule来检查特定的注释并执行@Before语句。
我的困惑在于如何执行规则中的@Before方法。有办法做到这一点吗?还是我需要传入测试类本身并执行@before方法(下面示例中的setup()
)?
public class NoBeforeRule implements TestRule {
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
if (description.getAnnotation(NoBefore.class) == null) {
// Is there something like `base.executeAllTheBefores()'
}
base.evaluate();
}
};
}
}
相关测试代码:
@Rule public NoBeforeRule mNoBeforeRule = new NoBeforeRule(this);
@Before
@Override
public void setup() {
}
@Test
public void testNeedSetup() {
// this should run setup()
}
@NoBefore
@Test
public void testNoSetup() {
// this should NOT run setup()
}
为什么不将测试划分为两个单独的测试类?需要设置的进入一个类,不需要设置的则进入另一个类。
没有任何规则(甚至指导方针)规定一个类的所有测试都必须进入一个测试类,事实上这是我经常做的事情。
您有一个或多个不需要通用设置的测试,这可能表明测试本身没有凝聚力,并且正在测试您的类的不同变体。例如,我可能有一堆方法,它们以特定的方式对阳性测试进行了模拟设置,但其他需要它的测试则针对失败场景进行了不同的配置。我将把这些测试分为两类——特别是用于积极场景的测试和用于失败场景的测试。
玩规则之类的游戏,明确地避免运行标准@Before
方法,只会让事情变得更加复杂,让你未来的自己或同事挠头,不知道为什么不运行
-
在自定义规则实现中调用setup()。
-
删除setup()上的@Before注释,因为包含@Rule将导致每次都运行自定义规则。
public class MyTest { class NoBeforeRule implements TestRule { @Override public Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { if (description.getAnnotation(NoBefore.class) == null) { setup(); } base.evaluate(); } }; } } @Rule public NoBeforeRule mNoBeforeRule = new NoBeforeRule(); public void setup() {} @Test public void testNeedSetup() { // this should run setup() } @NoBefore @Test public void testNoSetup() { // this should NOT run setup() } }
也许可以使用规则TestName
@Rule public TestName name = new TestName();
@Before
public void setup() {
if(listOfTestNeedSetup.contains(name.getMethodName()) {
// need setup
}
}