如何在 JUnit 5 中替换 WireMock @Rule 注释?
Posted
技术标签:
【中文标题】如何在 JUnit 5 中替换 WireMock @Rule 注释?【英文标题】:How to replace WireMock @Rule annotation in JUnit 5? 【发布时间】:2018-12-03 08:55:16 【问题描述】:我在我的测试中使用了 WireMock 并且有这样一行代码:
@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);
我想切换到 JUnit 5。所以我添加了下一个依赖项(使用 Gradle):
testCompile('org.junit.jupiter:junit-jupiter-engine:5.1.1')
但是当我尝试导入 @Rule
注释时没有任何建议。
我需要添加另一个 JUnit 依赖模块吗?还是 JUnit 5 不支持规则?如果没有,我该如何替换 @Rule
注释以使测试再次工作?
【问题讨论】:
查看这篇精彩的文章codeaffine.com/2016/04/06/replace-rules-in-junit5 没有直接替换,Junit Jupiter使用@Extension
而不是@Rlue
;开发人员需要移植他们的代码 - WireMock 还没有 done this yes。您可以自己实现@Extension
。
【参考方案1】:
一般而言,您在 JUnit 4 中对 @Rule
和 @ClassRule
所做的操作应该使用 @ExtendWith
和 Extension
完成,它们在 JUnit 5 中提供了非常接近的功能。
它作为标准的 JUnit 生命周期钩子工作,但它是在 Extension
类中提取的。与@Rule
类似,可以为测试类添加任意数量的Extension
s。
要处理这个问题,您有几种可能的方法:
保持 JUnit 4 方式(JUnit 5 拥有允许执行 JUnit 3 或 4 测试的 JUnit Vintage 部分)。 将@Rule
重写为Extension
。
使用@BeforeEach
和@AfterEach
钩子方法在类的每个测试中执行WireMockRule
完成的实际处理(启动服务器、执行测试和停止服务器)。
使用第三个库,该库在 JUnit 5 扩展方式中实现 WireMockRule 的等价物,例如 https://github.com/lanwen/wiremock-junit5
请注意,您的问题已在 the JUnit 5 Issues 中讨论过。
【讨论】:
有关制作扩展的快捷方式,请参阅答案***.com/a/66060677/1355930【参考方案2】:JUnit 4 注释 @Rule
和 @ClassRule
在 JUnit 5 中不存在。基本上有一个新的扩展模型可用于实现具有相同功能的扩展。这些扩展可以与@ExtendWith
注解一起使用。
junit-jupiter-migrationsupport 模块中对 JUnit 4 规则子集的迁移支持有限。不幸的是,它只限于ExternalResource
和Verifier
的子类。
在wiremock 正式支持JUnit 之前,您有一些解决方法:
-
使用 junit-vintage-engine 同时运行 JUnit 4 测试和 JUnit 5 测试。
在测试代码中自行启动和停止服务器。
使用第 3 方扩展程序,例如 wiremock-junit5 或 wiremock-extension。
【讨论】:
【参考方案3】:现在正式支持 WireMock 2.31.0 中的 JUnit 5 Jupiter。
这里的文档:http://wiremock.org/docs/junit-jupiter/
【讨论】:
【参考方案4】: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());
);
您可以使用PluginExtension
和TestResource.of
轻松创建自己的新JUnit 5 插件
@ExtendWith(PluginExtension.class)
class TestResourceIsActiveDuringTest
private WireMockServer server;
@Plugin
private TestResource someResource = TestResource.from(() -> server.start(),
() -> server.stop());
【讨论】:
DangerousRule...
?哈哈。疯狂的名字选择:)。
@DutA。我想要一个能让人们了解为什么它可能并不总是有效的名字;)【参考方案5】:
来自JUnit 5 user guide:
@Rule
和@ClassRule
不再存在;被@ExtendWith
和@RegisterExtension
取代。另见"Limited JUnit 4 Rule Support"。
不过,正如pointed out by Tom,WireMock 自 2.31.0 版起已全面支持 JUnit Jupiter:
// New JUnit 5 extension
@WireMockTest
class DeclarativeWireMockTest
@Test
void test_something_with_wiremock(WireMockRuntimeInfo wmRuntimeInfo)
// The static DSL will be automatically configured for you
stubFor(get("/static-dsl").willReturn(ok()));
// Instance DSL can be obtained from the runtime info parameter
WireMock wireMock = wmRuntimeInfo.getWireMock();
wireMock.register(get("/instance-dsl").willReturn(ok()));
// Info such as port numbers is also available
int port = wmRuntimeInfo.getHttpPort();
// Do some testing...
更多信息请参考corresponding docs。
【讨论】:
以上是关于如何在 JUnit 5 中替换 WireMock @Rule 注释?的主要内容,如果未能解决你的问题,请参考以下文章
使用 WireMock 的 Spring JUnit 测试中的多个应用程序上下文
如何在 JUnit Test Java 中替换 Mockito 以存根类