跳过@Before进行测试||有没有办法在TestRule中执行@Before方法?

时间:2015-04-09 15:50:47

标签: java unit-testing junit4 junit-rule

高级别,我有JUnit测试类,非常简单。我有几个@Tests和一个@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()
}

3 个答案:

答案 0 :(得分:2)

为什么不将测试分成两个独立的测试类?需要设置的那些进入一个类和不进入另一个类的那个。

没有规则(甚至指南)规定类的所有测试必须进入单个测试类,这实际上是我经常做的事情。

您有一个或多个不需要通用设置的测试的事实可能表明测试本身没有内聚性,并且正在测试您所测试的类的不同变体。例如,我可能有一堆方法,以特定的方式进行模拟设置以进行正面测试,但随后需要为故障情况配置不同的其他测试。我将这些测试分为两类 - 特别是积极场景和失败场景。

使用规则等明确地避免运行标准@Before方法会让事情变得更加复杂,并让你的未来或同事们为什么会摸不着头脑设置方法没有运行

答案 1 :(得分:1)

也许可以使用规则TestName

@Rule public TestName name = new TestName();

@Before 
public void setup() {
     if(listOfTestNeedSetup.contains(name.getMethodName()) {
        // need setup
     }
}

答案 2 :(得分:0)

  • 在自定义规则实现中调用 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()
       }
    }