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

如何在非测试方法中打印JUnit或Hamcrest的diff对比结果?

实现JSON字符串diff的可行方案

完全可以直接复用JUnit、Hamcrest生态的组件实现该需求,不需要手动实现diff逻辑。


方案1:复用JUnit 5内置断言输出结构化diff

JUnit 5(Jupiter)的Assertions.assertEquals方法本身就自带预期值与实际值的对比diff输出,直接在非测试代码中调用即可,无需依赖测试运行环境。
为了避免JSON格式排版差异导致的误判,建议先将两个JSON字符串统一格式化后再对比:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.jupiter.api.AssertionFailedError;
import org.junit.jupiter.api.Assertions;

public class JsonDiffTool {
    // 全局复用格式化配置
    private static final ObjectMapper JSON_MAPPER = new ObjectMapper()
            .enable(SerializationFeature.INDENT_OUTPUT);

    public static String compareJson(String expectedJson, String actualJson) {
        try {
            // 先把JSON字符串解析为对象再格式化,消除空格、换行、键顺序差异
            Object expectedObj = JSON_MAPPER.readValue(expectedJson, Object.class);
            Object actualObj = JSON_MAPPER.readValue(actualJson, Object.class);
            String expectedFormat = JSON_MAPPER.writeValueAsString(expectedObj);
            String actualFormat = JSON_MAPPER.writeValueAsString(actualObj);

            Assertions.assertEquals(expectedFormat, actualFormat);
            // 完全相等返回null
            return null;
        } catch (AssertionFailedError e) {
            // 异常消息中包含完整的expected/actual对比diff
            return e.getMessage();
        } catch (Exception e) {
            return "JSON解析异常:" + e.getMessage();
        }
    }
}

注意:如果不需要单元测试运行能力,仅需引入junit-jupiter-api依赖即可,不需要引入测试执行引擎等多余组件,不会增加太多依赖体积


方案2:使用兼容Hamcrest的JSON专用对比库输出类git diff

如果需要更贴近git diff的增减标记格式,可以使用json-unit库(兼容Hamcrest标准),它原生支持JSON结构化对比,输出会直接标记差异的JSON路径、增减内容,可读性更高:

import net.javacrumbs.jsonunit.JsonAssert;
import net.javacrumbs.jsonunit.core.Option;

public class JsonDiffTool {
    public static String getGitStyleDiff(String expectedJson, String actualJson) {
        try {
            // 可配置对比规则,比如是否忽略数组顺序、是否把null视为有效值
            JsonAssert.assertJsonEquals(expectedJson, actualJson,
                    JsonAssert.when(Option.TREAT_NULL_AS_VALUE, Option.IGNORING_ARRAY_ORDER));
            return null;
        } catch (AssertionError e) {
            return e.getMessage();
        }
    }
}

输出的diff会包含类似git的增减标记,数组、对象嵌套场景也能准确定位差异位置。


自定义调整说明

如果对默认输出格式不满意,可以直接捕获断言异常中的预期值、实际值字段,自行拼接为你需要的格式,无需完全依赖框架默认的消息输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:45:03