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

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


当前回答

使用这个库:https://github.com/lukas-krecan/JsonUnit

Pom:

<dependency>
    <groupId>net.javacrumbs.json-unit</groupId>
    <artifactId>json-unit-assertj</artifactId>
    <version>2.24.0</version>
    <scope>test</scope>
</dependency>

IGNORING_ARRAY_ORDER -忽略数组中的顺序

assertThatJson("{\"test\":[1,2,3]}")
  .when(Option.IGNORING_ARRAY_ORDER)
  .isEqualTo("{\"test\": [3,2,1]}");

其他回答

这可能会帮助那些使用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);
}

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

使用GSON

JsonParser parser = new JsonParser();
JsonElement o1 = parser.parse("{a : {a : 2}, b : 2}");
JsonElement o2 = parser.parse("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

编辑:自GSON v2.8.6起,实例方法JsonParser。不建议使用Parse。你必须使用静态方法JsonParser.parseString:

JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

下面的代码将更有助于比较两个JsonObject, JsonArray, JsonPrimitive和JasonElements。

private boolean compareJson(JsonElement json1, JsonElement json2) {
        boolean isEqual = true;
        // Check whether both jsonElement are not null
        if (json1 != null && json2 != null) {

            // Check whether both jsonElement are objects
            if (json1.isJsonObject() && json2.isJsonObject()) {
                Set<Entry<String, JsonElement>> ens1 = ((JsonObject) json1).entrySet();
                Set<Entry<String, JsonElement>> ens2 = ((JsonObject) json2).entrySet();
                JsonObject json2obj = (JsonObject) json2;
                if (ens1 != null && ens2 != null) {
                    // (ens2.size() == ens1.size())
                    // Iterate JSON Elements with Key values
                    for (Entry<String, JsonElement> en : ens1) {
                        isEqual = isEqual && compareJson(en.getValue(), json2obj.get(en.getKey()));
                    }
                } else {
                    return false;
                }
            }

            // Check whether both jsonElement are arrays
            else if (json1.isJsonArray() && json2.isJsonArray()) {
                JsonArray jarr1 = json1.getAsJsonArray();
                JsonArray jarr2 = json2.getAsJsonArray();
                if (jarr1.size() != jarr2.size()) {
                    return false;
                } else {
                    int i = 0;
                    // Iterate JSON Array to JSON Elements
                    for (JsonElement je : jarr1) {
                        isEqual = isEqual && compareJson(je, jarr2.get(i));
                        i++;
                    }
                }
            }

            // Check whether both jsonElement are null
            else if (json1.isJsonNull() && json2.isJsonNull()) {
                return true;
            }

            // Check whether both jsonElement are primitives
            else if (json1.isJsonPrimitive() && json2.isJsonPrimitive()) {
                if (json1.equals(json2)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else if (json1 == null && json2 == null) {
            return true;
        } else {
            return false;
        }
        return isEqual;
    }

您可以尝试JsonUnit。它可以比较两个JSON对象并报告差异。它建在杰克逊的顶部。

例如

assertThatJson("{\"test\":1}").isEqualTo("{\n\"test\": 2\n}");

结果

java.lang.AssertionError: JSON documents are different:
Different value found in node "test". Expected 1, got 2.