当前位置: 首页 > 知识库问答 >
问题:

如何在JUnit 4.12中组合@规则和@Class规则

隗俊誉
2023-03-14

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

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

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

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

共有3个答案

南门朗
2023-03-14

您无法区分@BeforeClass@前@AfterClass@后。有关添加此功能的原因的更多详细信息,请参阅拉取请求

后焕
2023-03-14

在每次测试之前和之后,将运行带有@Before@After注释的方法,而带有@Before class@AfterClass注释的方法将分别在类中第一次/最后一次测试之前和之后运行。

@规则的前/后方法在每次测试之前和之后执行,而@Class规则的前/后方法在整个测试类之前/之后运行。

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

杜阳炎
2023-03-14

您可以实现TestRule#apply,并使用Description的isTest和isSuite方法来确定您的TestRule应用于哪种类型的语句。

下面是一个示例界面,您可以构建该界面来给出一个规则,该规则在前有full、后有full、verifyClass、前有verifyClass、后有verifyClass、类型行为:

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();
    }
}
 类似资料:
  • 在JUnit 4.10及更低版本中,可以将规则注释为@规则和@ClassRur。这意味着规则会在类之前/之后以及每次测试之前/之后被调用。这样做的一个可能原因是设置一个昂贵的外部资源(通过@ClassRur调用),然后廉价地重置它(通过@Rur调用)。 从JUnit 4.11开始,@规则字段必须是非静态的,@ClassRule字段必须是静态的,因此上述操作不再可行。 有明确的变通方法(例如,明确地

  • 混合配置的规则项之间的叠加使用是通过数据源名称和表名称关联的。 如果前一个规则是面向数据源聚合的,下一个规则在配置数据源时,则需要使用前一个规则配置的聚合后的逻辑数据源名称; 同理,如果前一个规则是面向表聚合的,下一个规则在配置表时,则需要使用前一个规则配置的聚合后的逻辑表名称。 配置项说明 <beans xmlns="http://www.springframework.org/schema/b

  • 混合配置的规则项之间的叠加使用是通过数据源名称和表名称关联的。 如果前一个规则是面向数据源聚合的,下一个规则在配置数据源时,则需要使用前一个规则配置的聚合后的逻辑数据源名称; 同理,如果前一个规则是面向表聚合的,下一个规则在配置表时,则需要使用前一个规则配置的聚合后的逻辑表名称。 配置项说明 # 数据源配置 # 数据源名称,多数据源以逗号分隔 spring.shardingsphere.datas

  • 混合配置的规则项之间的叠加使用是通过数据源名称和表名称关联的。 如果前一个规则是面向数据源聚合的,下一个规则在配置数据源时,则需要使用前一个规则配置的聚合后的逻辑数据源名称; 同理,如果前一个规则是面向表聚合的,下一个规则在配置表时,则需要使用前一个规则配置的聚合后的逻辑表名称。 配置项说明 dataSources: # 配置真实存在的数据源作为名称 write_ds: # ...省略

  • 混合配置的规则项之间的叠加使用是通过数据源名称和表名称关联的。 如果前一个规则是面向数据源聚合的,下一个规则在配置数据源时,则需要使用前一个规则配置的聚合后的逻辑数据源名称; 同理,如果前一个规则是面向表聚合的,下一个规则在配置表时,则需要使用前一个规则配置的聚合后的逻辑表名称。 配置项说明 /* 数据源配置 */ HikariDataSource writeDataSource0 = new H

  • 我有以下解析器规则: 和以下lexer规则: 有了上面的规则,我想能够写出下面的代码: