You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WireMock使用matchingJsonPath带StringValuePattern时抛出空异常问题

问题

我尝试验证发送给下游服务的POST请求体是否包含正确内容/值,但出现空指针异常。

测试代码如下:

import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.exactly;
import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;


@Test
void test() throws Exception {
    mockMvc.perform(
            post(...)
            .andExpect(status().isOk());

    await().atMost(Duration.ofSeconds(5)).untilAsserted(() -> verify(exactly(1), postRequestedFor(urlPathMatching("my-url-path"))
            .withRequestBody(matchingJsonPath("$.field1", equalTo("1")))));
}

运行时报错:

com.github.tomakehurst.wiremock.matching.PathPattern$SubExpressionException: Warning: JSON path expression '$.accountId' failed to match document '' because of error 'json string can not be null or empty'


Caused by: java.lang.IllegalArgumentException: json string can not be null or empty
   at wiremock.com.jayway.jsonpath.internal.Utils.notEmpty(Utils.java:401)
   at wiremock.com.jayway.jsonpath.internal.ParseContextImpl.parse(ParseContextImpl.java:36)
   at wiremock.com.jayway.jsonpath.JsonPath.read(JsonPath.java:550)
   at com.github.tomakehurst.wiremock.matching.MatchesJsonPathPattern.getExpressionResult(MatchesJsonPathPattern.java:122)
   ... 18 more

改用这种表达式映射能正常运行:

.withRequestBody(matchingJsonPath("$.[?(@.field1 == 1)]"))));

我的请求体JSON是:

{
  "field1": "1"
}

请问正确使用StringValuePattern的方式是什么?


原因分析

报错提示请求体为空字符串,但实际请求体是合法JSON,问题出在WireMock的matchingJsonPath重载方法行为差异:

  • 双参数版本matchingJsonPath(String path, StringValuePattern valuePattern)会先尝试解析请求体为JSON,若请求未携带application/json的Content-Type头,WireMock无法识别请求体格式,会将其当作空字符串处理,触发解析失败。
  • 单参数版本matchingJsonPath(String expression)直接用JsonPath表达式匹配,内部处理逻辑不同,不会触发该解析问题。

正确用法

有三种可靠的解决方式:

方式1:指定请求Content-Type

在匹配规则中添加Content-Type验证,确保WireMock识别请求体为JSON:

verify(exactly(1), postRequestedFor(urlPathMatching("my-url-path"))
        .withHeader("Content-Type", equalTo("application/json"))
        .withRequestBody(matchingJsonPath("$.field1", equalTo("1"))));

方式2:使用equalToJson匹配指定字段

若只需验证特定字段,可直接用equalToJson配合忽略额外字段的选项:

verify(exactly(1), postRequestedFor(urlPathMatching("my-url-path"))
        .withRequestBody(equalToJson("{\"field1\": \"1\"}", true, false)));

第三个参数false表示忽略请求体中除field1外的其他字段。

方式3:用matching替代equalTo

调整值匹配的写法,使用matching适配双参数的matchingJsonPath:

verify(exactly(1), postRequestedFor(urlPathMatching("my-url-path"))
        .withRequestBody(matchingJsonPath("$.field1", matching("1"))));

内容的提问来源于stack exchange,提问作者noobgrammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:01:08