我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
我正在寻找一个JSON解析库,支持比较忽略子顺序的两个JSON对象,特别是用于从web服务返回的单元测试JSON。
有任何主要的JSON库支持这一点吗?org。Json库只是做一个引用比较。
当前回答
下面的代码将更有助于比较两个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;
}
其他回答
我将使用http://json.org/java/上的库,并修改JSONObject和JSONArray的equals方法来进行深入的相等性测试。为了确保它可以不分子元素的顺序重新排序,您所需要做的就是用TreeMap替换内部映射,或者使用Collections.sort()之类的东西。
如果您已经在使用JUnit,那么最新版本现在使用Hamcrest。它是一个通用的匹配框架(对单元测试特别有用),可以扩展以构建新的匹配器。
有一个名为hamcrest-json的小型开源库,它具有json感知匹配。它有良好的文档、测试和支持。以下是一些有用的链接:
源代码 主页 主匹配器的Javadocs:
使用JSON库org.json.simple对象的示例代码:
Assert.assertThat(
jsonObject1.toJSONString(),
SameJSONAs.sameJSONAs(jsonObject2.toJSONString()));
可选地,您可以(1)允许“任意顺序”数组和(2)忽略额外的字段。
由于Java有多种JSON库(Jackson, GSON, JSON -lib等),hamcrest-json支持JSON文本(如Java .lang. string),以及原生支持来自Douglas Crockford的JSON库org.json的对象是很有用的。
最后,如果不使用JUnit,可以直接使用Hamcrest进行断言。(我在这里写过。)
使用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);
试试天空尖叫者的圣像。
它的非严格模式有两个主要优点,使其不那么脆弱:
对象的可扩展性(例如,期望值为{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对象时非常重要。
对于像我这样想要使用Jackson的人,您可以使用json-unit。
JsonAssert.assertJsonEquals(jsonNode1, jsonNode2);
错误给出了关于不匹配类型的有用反馈:
java.lang.AssertionError: JSON documents have different values:
Different value found in node "heading.content[0].tag[0]". Expected 10209, got 10206.