如何在JUnit 4.12中组合@Rule和@ClassRule

时间:2015-09-03 19:49:35

标签: java junit junit4 junit-rule

根据the 4.12 release notes,可以使用@Rule和@ClassRule注释测试类的静态成员:

  

使用@Rule和@ClassRule注释的静态成员现在被视为有效。这意味着可以使用单个规则在类之前/之后(例如,设置/拆除外部资源)和测试之间(例如,重置外部资源)执行操作,

我想使用此功能在文件中的所有测试开始时初始化资源,在每次测试之间对资源进行一些清理,并在所有测试完成后处理它。此资源当前由扩展ExternalResource的类表示。

在我的beforeafter方法中,如何在所有测试之前/之后区分""和"每次测试之前/之后"?我是否需要使用TestRule的其他/自定义实现来完成此操作?

4 个答案:

答案 0 :(得分:3)

您可以实施TestRule#apply并使用isTest的{​​{1}}和isSuite方法来确定Description Statement的{​​{1}}种类适用于。

以下是您可以构建的示例界面,以提供具有完整TestRulebeforeafterverifybeforeClass,{{1类型行为:

afterClass

答案 1 :(得分:1)

使用@Before@After注释的方法将在每次测试之前和之后运行,而使用@BeforeClass@AfterClass注释的方法将在第一次测试之前和之后运行/分别在班上的​​最后一次考试。

@Rule的before / after方法在每次测试之前和之后执行,而@ClassRule的before / after方法在整个测试类之前/之后运行。

只要处理程序方法对两种情况都做出正确反应,就可以将ExternalResource用于@Rule@ClassRule情况。据我所知,在文档中,没有办法区分规则类方法中的两个规则类别。如果对两种情况使用规则类,则对它们应用相同的情况。

答案 2 :(得分:0)

您无法区分@BeforeClass@Before@AfterClass@After。有关添加此功能的原因的详细信息,请参阅pull request

答案 3 :(得分:0)

您可以创建自己的规则,同时实现TestRuleMethodRule

public SharableExternalResource implements TestRule, MethodRule {

  public final Statement apply(
      final Statement base, Description description) {
    return
        new Statement() {
          @Override
          public void evaluate() throws Throwable {
            beforeClass();

            List<Throwable> errors = new ArrayList<Throwable>();
            try {
                base.evaluate();
            } catch (Throwable t) {
                errors.add(t);
            } finally {
                try {
                    afterClass();
                } catch (Throwable t) {
                    errors.add(t);
                }
            }
            MultipleFailureException.assertEmpty(errors);
          }
        };
  }

  public final Statement apply(
      Statement base, FrameworkMethod method, Object target) {
    return
        new Statement() {
          @Override
          public void evaluate() throws Throwable {
            before();

            List<Throwable> errors = new ArrayList<Throwable>();
            try {
                base.evaluate();
            } catch (Throwable t) {
                errors.add(t);
            } finally {
                try {
                    after();
                } catch (Throwable t) {
                    errors.add(t);
                }
            }
            MultipleFailureException.assertEmpty(errors);
          }
        };
  }

  public void beforeClass() throws Exception {
    // do nothing
  }

  protected void before() throws Exception {
    // do nothing
  }

  protected void after() throws Exception {
    // do nothing
  }

  public void afterClass() throws Exception {
    // do nothing
  }
}