我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。

有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。


当前回答

我会这么做,

JSONObject obj1 = /*json*/;
JSONObject obj2 = /*json*/;

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(obj1.toString());
JsonNode tree2 = mapper.readTree(obj2.toString());

return tree1.equals(tree2);

其他回答

我将使用http://json.org/java/上的库,并修改JSONObject和JSONArray的equals方法来进行深入的相等性测试。为了确保它可以不分子元素的顺序重新排序,您所需要做的就是用TreeMap替换内部映射,或者使用Collections.sort()之类的东西。

我知道它通常只用于测试,但你可以使用Hamcrest JSON中的comparitorSameJSONAs。

Hamcrest JSON SameJSONAs

有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。

但org。Json支持这个!使用similar()代替equals()。

我所做的是使用gson将jsons转换为map,并使用assertj比较这些映射:

Map<Object, Object> resMap = gson.fromJson(res, new TypeToken<Map<Object, Object>>() {}.getType());
Map<Object, Object> expectedMap = gson.fromJson(expected, new TypeToken<Map<Object, Object>>() {}.getType());
Assertions.assertThat(resMap).usingRecursiveComparison().isEqualTo(expectedMap);

结果是递归地比较了所有属性!!

这可能会帮助那些使用Spring Framework的人。你可以重用内部使用的在ResultActions上做断言(用于控制器测试):

进口:org.springframework.test.util.JsonExpectationsHelper

你可以编写带有详细输出的测试:

java.lang.AssertionError: someObject.someArray[1].someInternalObject2.value
Expected: 456
     got: 4567

测试代码:

@Test
void test() throws Exception {

    final String json1 =
        "{" +
        "  'someObject': {" +
        "    'someArray': [" +
        "      {" +
        "        'someInternalObject': {" +
        "          'value': '123'" +
        "        }" +
        "      }," +
        "      {" +
        "        'someInternalObject2': {" +
        "          'value': '456'" +
        "        }" +
        "      }" +
        "    ]" +
        "  }" +
        "}";

    final String json2 =
        "{" +
        "  'someObject': {" +
        "    'someArray': [" +
        "      {" +
        "        'someInternalObject': {" +
        "          'value': '123'" +
        "        }" +
        "      }," +
        "      {" +
        "        'someInternalObject2': {" +
        "          'value': '4567'" +
        "        }" +
        "      }" +
        "    ]" +
        "  }" +
        "}";

    new JsonExpectationsHelper().assertJsonEqual(json1, json2, true);
}