如何在Junit 5中替换@Rule注释?

时间:2018-06-24 17:29:05

标签: java junit5 junit-rule

我在测试中使用Wiremock,并具有以下代码行:

@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);

我想切换到Junit5。所以我添加了下一个依赖项(使用gradle):

testCompile('org.junit.jupiter:junit-jupiter-engine:5.1.1')

但是当我尝试导入@Rule注释时没有任何建议。 我是否需要添加另一个依赖于junit的模块?还是Junit5不支持规则?如果没有,我该如何替换@Rule批注以使测试再次起作用? 谢谢。

3 个答案:

答案 0 :(得分:3)

一般而言,您在JUnit 4中对@Rule@ClassRule所做的操作应该与@ExtendWithExtension一起完成,而它们在JUnit中提供了非常紧密的功能5.
它用作标准的JUnit生命周期挂钩,但是它是在Extension类中提取的。与@Rule类似,可以为测试类添加所需数量的Extension

要解决此问题,您可以采用以下几种方法:

  • 保持JUnit 4方式(JUnit 5拥有允许执行JUnit 3或4测试的JUnit Vintage部分)。
  • @Rule重写为Extension
  • 使用WireMockRule@BeforeEach挂钩方法在类的每个测试中执行@AfterEach完成的实际处理(启动服务器,执行测试并停止服务器)。
  • 使用第三个库,该库以JUnit 5扩展方式实现等效的WireMockRule,例如https://github.com/lanwen/wiremock-junit5

请注意,您的问题已在the JUnit 5 Issues中进行了讨论。

答案 1 :(得分:1)

JUnit 4批注@Rule@ClassRule在JUnit 5中不存在。基本上,存在一个新的扩展模型,可用于实现具有相同功能的扩展。这些扩展名可以与@ExtendWith批注一起使用。

junit-jupiter-migrationsupport 模块中对JUnit 4规则的一部分的迁移支持有限。不幸的是,它仅限于ExternalResourceVerifier的子类。

在wiremock正式支持JUnit之前,您有一些解决方法:

  1. 与使用 junit-vintage-engine 的JUnit 5测试并排运行JUnit 4测试。
  2. 使用测试代码自行启动和停止服务器。
  3. 使用第三方分机,例如wiremock-junit5wiremock-extension

答案 2 :(得分:0)

https://github.com/webcompere/java-test-gadgets 项目可让您通过多种方式解决此问题。

您可以通过 DangerousRuleAdapter 使用它对 JUnit 4 规则的支持 - 这将尝试将任何 JUnit 4 规则转换为 Plugin

@ExtendWith(PluginExtension.class)
public class DangerousRuleAdapterExampleTest {
    @Plugin
    private DangerousRuleAdapter<WireMockRule> adapter = 
        new DangerousRuleAdapter<>(new WireMockRule());

    @Test
    void theTest() {
        // use wiremock rule here
        WireMockRule rule = adapter.get();
    }

规则适配器无法处理检查测试类或测试方法的规则,但会尝试运行规则。

还支持围绕某些代码运行规则:

    TemporaryFolder temporaryFolder = new TemporaryFolder();

    // let's use this temp folder with some test code
    executeWithRule(temporaryFolder, () -> {
        // here, the rule is _active_
        callSomethingThatUses(temporaryFolder.getRoot());
    });

并且您可以使用 PluginExtensionTestResource.of

轻松创建自己的新 JUnit 5 插件
@ExtendWith(PluginExtension.class)
class TestResourceIsActiveDuringTest {
    private WireMockServer server;

    @Plugin
    private TestResource someResource = TestResource.from(() -> server.start(),
                                                          () -> server.stop());