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

如何在MockMvc中从jsonPath()获取字符串并比较两个jsonPath值

如何在Spring MVC测试中比较两个JSON路径的值

你遇到的问题很典型——jsonPath()方法返回的是JsonPathResultMatchers对象(这就是你看到类名输出的原因),而不是JSON属性的实际值,所以直接把它传给equalTo()肯定不会生效。下面给你几种可行的解决方法:

方法一:提取响应体后手动比较

先获取完整的响应体,再用JsonPath.read()分别读取两个属性的值,最后用断言完成比较:

// 执行请求并获取测试结果
MvcResult result = mockMvc.perform(get(requestURL))
        .andReturn();

// 读取响应体的字符串内容
String responseBody = result.getResponse().getContentAsString();

// 用JsonPath分别提取两个属性的实际值
String prop1Value = JsonPath.read(responseBody, "$.prop1");
String prop2Value = JsonPath.read(responseBody, "$.prop2");

// 断言两个值相等
assertEquals(prop1Value, prop2Value);

这种方式直观易懂,还能方便你对提取出的值做额外的逻辑处理。

方法二:在断言中动态提取值

利用Lambda表达式在andExpect中动态获取第一个属性的值,再用它来校验第二个属性:

mockMvc.perform(get(requestURL))
        .andExpect(result -> {
            // 从响应体中提取prop1的实际值
            String prop1 = JsonPath.read(result.getResponse().getContentAsString(), "$.prop1");
            // 直接断言prop2的值与prop1一致
            result.andExpect(jsonPath("$.prop2", equalTo(prop1)));
        });

这种写法更紧凑,不需要单独保存测试结果对象,适合简单的同响应内属性比较场景。

方法三:自定义Hamcrest匹配器(复用场景)

如果需要多次复用这种“比较两个JSON路径值”的逻辑,可以自定义一个Hamcrest匹配器:

public class JsonPathEqualToMatcher extends TypeSafeMatcher<String> {
    private final String targetJsonPath;
    private final String comparedJsonPath;

    public JsonPathEqualToMatcher(String targetJsonPath, String comparedJsonPath) {
        this.targetJsonPath = targetJsonPath;
        this.comparedJsonPath = comparedJsonPath;
    }

    @Override
    protected boolean matchesSafely(String responseBody) {
        Object targetValue = JsonPath.read(responseBody, targetJsonPath);
        Object comparedValue = JsonPath.read(responseBody, comparedJsonPath);
        return Objects.equals(targetValue, comparedValue);
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("JSON路径 ").appendValue(targetJsonPath)
                   .appendText(" 的值等于路径 ").appendValue(comparedJsonPath).appendText(" 的值");
    }

    public static JsonPathEqualToMatcher equalToJsonPath(String targetJsonPath, String comparedJsonPath) {
        return new JsonPathEqualToMatcher(targetJsonPath, comparedJsonPath);
    }
}

然后在测试中直接调用:

mockMvc.perform(get(requestURL))
        .andExpect(result -> {
            String responseBody = result.getResponse().getContentAsString();
            assertThat(responseBody, equalToJsonPath("$.prop1", "$.prop2"));
        });

这种方式能让重复的测试逻辑更简洁,适合大型测试用例场景。

注意:如果你的属性是数字、布尔值等非字符串类型,记得调整JsonPath.read()的泛型类型,避免类型转换错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:31:22