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

Spring Boot中MockMvc的JsonPath配置及表达式假阳性问题

JsonPath配置与表达式问题解答

一、JsonPath原生配置方式

JsonPath本身可通过如下代码配置:

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;

// ...

Configuration configuration = Configuration
    .builder()
    .options(Option.REQUIRE_PROPERTIES)
    .build();

JsonPath
    .using(configuration)
    .parse(someJson)
    .read("$.*.bar");

该示例启用了Option.REQUIRE_PROPERTIES配置项,当指定路径不存在时会直接抛出异常。

二、Spring Boot MockMvc中配置JsonPath的REQUIRE_PROPERTIES

Spring MockMvc默认的jsonPath匹配器未直接开放JsonPath配置入口,可通过自定义ResultMatcher实现需求:

自定义匹配工具类

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import org.springframework.test.web.servlet.ResultMatcher;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.hamcrest.MatcherAssert.assertThat;

public class CustomJsonPathMatchers {
    // 预先配置好需要的JsonPath规则
    private static final Configuration CONFIG = Configuration.builder()
            .options(Option.REQUIRE_PROPERTIES)
            .build();

    public static ResultMatcher jsonPathWithConfig(String expression, org.hamcrest.Matcher<?> matcher) {
        return content().string(jsonContent -> {
            // 使用自定义配置解析JSON并提取结果
            Object result = JsonPath.using(CONFIG).parse(jsonContent).read(expression);
            // 用Hamcrest匹配器验证结果
            assertThat(result, matcher);
            return true;
        });
    }
}

在测试中使用

import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static com.yourpackage.CustomJsonPathMatchers.jsonPathWithConfig;
import static org.hamcrest.Matchers.isEmptyCollection;

// ...

mockMvc
    .perform(get("/test"))
    .andExpect(status().isOk())
    .andExpect(jsonPathWithConfig("$.*.bar", isEmptyCollection()));

三、JsonPath表达式假阳性问题解决

场景说明

输入JSON:

[
  {"animal": "cat", "meow": true},
  {"animal": "cat", "meow": true},
  {"animal": "cat", "bark": true}
]

原表达式jsonPath("$.[?(@.animal == 'cat')].meow").value(everyItem(equalTo(true)))出现假阳性,原因是第三个对象无meow字段,JsonPath会返回null,部分场景下匹配器未正确识别null与true的差异。

正确写法

方法1:JsonPath层面直接过滤验证

直接在表达式中同时过滤animal为cat和meow等于true的条件,再验证结果数量与总cat数量一致:

import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

// 验证总共有3个cat
mockMvc.perform(get("/test"))
    .andExpect(jsonPath("$.[?(@.animal == 'cat')]").value(hasSize(3)))
    // 验证所有cat都满足meow为true(结果数量需等于3才通过)
    .andExpect(jsonPath("$.[?(@.animal == 'cat' && @.meow == true)]").value(hasSize(3)));

方法2:结合匹配器排除null值

如果需要保留原表达式结构,可通过Hamcrest的组合匹配器同时验证所有元素为true且无null值:

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.nullValue;

mockMvc.perform(get("/test"))
    .andExpect(jsonPath("$.[?(@.animal == 'cat')].meow")
        .value(allOf(
            everyItem(equalTo(true)),
            not(hasItem(nullValue()))
        )));

内容的提问来源于stack exchange,提问作者István Béksy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:45:36