我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
当前回答
其他方法似乎都不太合适,所以我写下了这个:
private boolean jsonEquals(JsonNode actualJson, JsonNode expectJson) {
if(actualJson.getNodeType() != expectJson.getNodeType()) return false;
switch(expectJson.getNodeType()) {
case NUMBER:
return actualJson.asDouble() == expectJson.asDouble();
case STRING:
case BOOLEAN:
return actualJson.asText().equals(expectJson.asText());
case OBJECT:
if(actualJson.size() != expectJson.size()) return false;
Iterator<String> fieldIterator = actualJson.fieldNames();
while(fieldIterator.hasNext()) {
String fieldName = fieldIterator.next();
if(!jsonEquals(actualJson.get(fieldName), expectJson.get(fieldName))) {
return false;
}
}
break;
case ARRAY:
if(actualJson.size() != expectJson.size()) return false;
List<JsonNode> remaining = new ArrayList<>();
expectJson.forEach(remaining::add);
// O(N^2)
for(int i=0; i < actualJson.size(); ++i) {
boolean oneEquals = false;
for(int j=0; j < remaining.size(); ++j) {
if(jsonEquals(actualJson.get(i), remaining.get(j))) {
oneEquals = true;
remaining.remove(j);
break;
}
}
if(!oneEquals) return false;
}
break;
default:
throw new IllegalStateException();
}
return true;
}
其他回答
我将使用http://json.org/java/上的库,并修改JSONObject和JSONArray的equals方法来进行深入的相等性测试。为了确保它可以不分子元素的顺序重新排序,您所需要做的就是用TreeMap替换内部映射,或者使用Collections.sort()之类的东西。
试试天空尖叫者的圣像。
它的非严格模式有两个主要优点,使其不那么脆弱:
对象的可扩展性(例如,期望值为{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对象时非常重要。
JSONObject中的toMap()已经可以很好地处理嵌套对象和数组。
因为java.util.Map接口指定检查映射而不是顺序,所以比较map是可以的,也是递归的。
json1 = new JSONObject("{...}");
json2 = new JSONObject("{...}");
json1.toMap().equals(json2.toMap());
它可以很好地处理任何顺序和嵌套元素。
然而,对于额外的/被忽略的元素,它将不起作用。如果这些是已知的,您可以在调用映射上的等号之前删除它们。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
但org。Json支持这个!使用similar()代替equals()。
使用这个库: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]}");