我使用 Cucumber 和 WireMock 进行 Spring-Boot 应用程序和集成测试。 在常规非并行执行模式下执行测试工作正常,没有任何问题,但是当切换为并行时,
cucumber.execution.parallel.enabled
为 true
,它开始失败。例外:
com.github.tomakehurst.wiremock.common.JsonException:
{
"errors" : [ {
"code" : 10,
"source" : {
"pointer" : "/code"
},
"title" : "Error parsing JSON",
"detail" : "Unrecognized field \"code\" (class com.github.tomakehurst.wiremock.common.Errors), not marked as ignorable"
} ]
}
at com.github.tomakehurst.wiremock.common.JsonException.fromJackson(JsonException.java:53)
at com.github.tomakehurst.wiremock.common.Json.read(Json.java:60)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.safelyExecuteRequest(HttpAdminClient.java:519)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.executeRequest(HttpAdminClient.java:489)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.executeRequest(HttpAdminClient.java:466)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.addStubMapping(HttpAdminClient.java:146)
at com.github.tomakehurst.wiremock.client.WireMock.register(WireMock.java:414)
at com.github.tomakehurst.wiremock.client.WireMock.register(WireMock.java:409)
at com.github.tomakehurst.wiremock.client.WireMock.givenThat(WireMock.java:115)
at com.github.tomakehurst.wiremock.client.WireMock.stubFor(WireMock.java:119)
WireMock.stubFor
应该是线程安全的操作吗?基于异常,看起来没有。如果非线程安全,可以采取哪些解决方法(同步/锁定 stubFor
的所有执行)?
存根初始化示例:
WireMock.stubFor(post(urlPathMatching("/test"))
.withRequestBody(equalToJson(..))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(..)));
WireMock 的创建方式如下:
WireMockServer wireMock = new WireMockServer(options()
.port(8000)
.extensions(new ResponseTemplateTransformer(true))
.notifier(new ConsoleNotifier(true)));
wireMock.start();
configureFor(8000);
版本:
com.github.tomakehurst:wiremock-jre8-standalone:2.33.0
在我的仓库中替换类
com.github.tomakehurst.wiremock.client.HttpAdminClient
并添加额外的日志后,发现存根定义执行期间的响应正文是{"code":"404.null.55","message":"Not Found"}
。
问题是请求针对错误的端口,它使用默认端口 8080 而不是配置的 8000。在我的例子中,端口 8000 是为 WireMock 服务器配置的,端口 8080 是从 Spring Boot 测试中为 Tomcat 配置的。
最初,当 Spring 上下文启动时,代码通过线程
main
的端口 8000 配置 WireMock 服务器,方法如下:
WireMockServer wireMock = new WireMockServer(options()
.port(8000)
.extensions(new ResponseTemplateTransformer(true))
.notifier(new ConsoleNotifier(true)));
wireMock.start();
configureFor(8000);
之后,
WireMock.stubFor(..)
从另一个线程调用(由于Cucumber的并行执行模式)。由于在 WireMock
内部实现,它具有线程本地 defaultInstance
,应使用调用线程中的适当端口进行额外配置。
因此,我更新了代码,在每次调用
WireMock.configureFor(8000);
之前调用 WireMock.stubFor(..)
,它解决了问题。
我遇到的第一个异常是
JsonException
,是由于在HttpAdminClient中没有正确处理404客户端错误代码,因为它的错误不是来自Wire Mock服务器,而是可能来自任何其他服务器。
我将提出一个问题或贡献一个修复程序来修复描述性错误,并在出现 404 错误代码时显式指定使用的端口,以便库能够优雅地处理此类情况。