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

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


当前回答

JSONObject中的toMap()已经可以很好地处理嵌套对象和数组。

因为java.util.Map接口指定检查映射而不是顺序,所以比较map是可以的,也是递归的。

json1 = new JSONObject("{...}");
json2 = new JSONObject("{...}");
json1.toMap().equals(json2.toMap());

它可以很好地处理任何顺序和嵌套元素。

然而,对于额外的/被忽略的元素,它将不起作用。如果这些是已知的,您可以在调用映射上的等号之前删除它们。

其他回答

使用这个库: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]}");

试试天空尖叫者的圣像。

它的非严格模式有两个主要优点,使其不那么脆弱:

对象的可扩展性(例如,期望值为{id:1},仍然会通过:{id:1,moredata:'x'}。) 宽松的数组排序(例如[‘狗’,‘猫’]= =[“猫”,“狗”])

在严格模式下,它更像json-lib的test类。

测试是这样的:

@Test
public void testGetFriends() {
    JSONObject data = getRESTData("/friends/367.json");
    String expected = "{friends:[{id:123,name:\"Corby Page\"}"
        + ",{id:456,name:\"Solomon Duskis\"}]}";
    JSONAssert.assertEquals(expected, data, false);
}

JSONAssert.assertEquals()调用中的参数是expectedJSONString, actualDataString和isStrict。

结果消息非常清晰,这在比较非常大的JSON对象时非常重要。

要比较json,我建议使用我的JSONCompare库: https://github.com/fslev/json-compare

// Compare by regex
String expected = "{\"a\":\".*me.*\"}";
String actual = "{\"a\":\"some text\"}";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no extra elements
String expected = "[1,\"test\",4,\"!.*\"]";
String actual = "[4,1,\"test\"]";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[\"text\",\"test\"]";
JSONCompare.assertEquals(expected, actual);  // True

// Check expected array has no numbers
String expected = "[\"\\\\\\d+\"]";
String actual = "[2018]";
JSONCompare.assertNotEquals(expected, actual);  // True

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

Hamcrest JSON SameJSONAs

我做的一件事是将两个对象读入HashMap,然后与常规的assertEquals()进行比较。它将调用哈希映射的equals()方法,该方法将递归地比较其中的所有对象(它们将是其他哈希映射或一些单值对象,如字符串或整数)。这是使用Codehaus的Jackson JSON解析器完成的。

assertEquals(mapper.readValue(expectedJson, new TypeReference<HashMap<String, Object>>(){}), mapper.readValue(actualJson, new TypeReference<HashMap<String, Object>>(){}));

如果JSON对象是一个数组,则可以使用类似的方法。