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

mar*_*oop 5 java junit junit4 junit-rule

根据4.12发行说明,可以使用@Rule和@ClassRule注释测试类的静态成员:

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

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

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

Bra*_*don 5

您可以实现TestRule#apply,使用isTestisSuite方法Description,以确定什么样的StatementTestRule被应用到。

这里的界面,你可以建立给具有完全的规则为例beforeafterverifybeforeClassafterClassverifyClass类型的行为:

public interface CombinedRule extends TestRule {
    default Statement apply(Statement base, Description description) {
        if (description.isTest()) {
            return new Statement() {
                public void evaluate() throws Throwable {
                    before();
                    try {
                        base.evaluate();
                        verify();
                    } finally {
                        after();
                    }
                }
            };
        }
        if (description.isSuite()) {
            return new Statement() {
                public void evaluate() throws Throwable {
                    beforeClass();
                    try {
                        base.evaluate();
                        verifyClass();
                    } finally {
                        afterClass();
                    }
                }
            };
        }
        return base;
    }

    default void before() throws Exception {
        //let the implementer decide whether this method is useful to implement
    }

    default void after() {
        //let the implementer decide whether this method is useful to implement
    }

    /**
     * Only runs for Tests that pass
     */
    default void verify() {
        //let the implementer decide whether this method is useful to implement
    }

    default void beforeClass() throws Exception {
        before();
    }

    default void afterClass() {
        after();
    }

    /**
     * Only runs for Suites that pass
     */
    default void verifyClass() {
        verify();
    }
}
Run Code Online (Sandbox Code Playgroud)