主要的JSON库中是否有任何一个支持此功能?org.json库仅执行引用比较。
尝试使用Skyscreamer的JSONAssert。
它的非严格模式具有两个主要优点,使其更加灵活:
在严格模式下,它的行为更像json-lib的测试类。
测试案例如下所示:
@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对象时非常重要。
JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);
NON_EXTENSIBLE模式意味着任何新字段或缺失字段会导致失败,但顺序不会。使用false会启动宽松模式,该模式不会报告任何额外或缺少的子元素。 - Dan Templepublic boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) {
return false;
}
ObjectNode other = (ObjectNode) o;
if (other.size() != size()) {
return false;
}
if (_children != null) {
for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
String key = en.getKey();
JsonNode value = en.getValue();
JsonNode otherValue = other.get(key);
if (otherValue == null || !otherValue.equals(value)) {
return false;
}
}
}
return true;
}
使用 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 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);
使用这个库: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]}");
你可以尝试使用json-lib库中的JSONAssert类:
JSONAssert.assertEquals(
"{foo: 'bar', baz: 'qux'}",
JSONObject.fromObject("{foo: 'bar', baz: 'xyzzy'}")
);
输出结果:
junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>
JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }");
错误信息为:
junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
- Dan Temple如果你已经在使用JUnit,最新版本现在采用了Hamcrest。它是一个通用的匹配框架(特别适用于单元测试),可以扩展以构建新的匹配器。
有一个名为hamcrest-json
的小型开源库,具有JSON感知匹配功能。 它有很好的文档、测试和支持。以下是一些有用的链接:
一些使用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
原生支持的对象转换成 JSON 对象。
最后,如果你没有使用 JUnit,你可以直接使用 Hamcrest 进行断言。(我在这里写过相关内容。)
你可以尝试使用JsonUnit。它可以比较两个JSON对象并报告差异。这是在Jackson的基础上构建的。
例如:
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.
我正在使用这个(与org.json.*一起),对我来说很好用:
package com.project1.helpers;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class JSONUtils {
public static boolean areEqual(Object ob1, Object ob2) throws JSONException {
Object obj1Converted = convertJsonElement(ob1);
Object obj2Converted = convertJsonElement(ob2);
return obj1Converted.equals(obj2Converted);
}
private static Object convertJsonElement(Object elem) throws JSONException {
if (elem instanceof JSONObject) {
JSONObject obj = (JSONObject) elem;
Iterator<String> keys = obj.keys();
Map<String, Object> jsonMap = new HashMap<>();
while (keys.hasNext()) {
String key = keys.next();
jsonMap.put(key, convertJsonElement(obj.get(key)));
}
return jsonMap;
} else if (elem instanceof JSONArray) {
JSONArray arr = (JSONArray) elem;
Set<Object> jsonSet = new HashSet<>();
for (int i = 0; i < arr.length(); i++) {
jsonSet.add(convertJsonElement(arr.get(i)));
}
return jsonSet;
} else {
return elem;
}
}
}
我所做的一件事情,产生了惊人的效果,就是将两个对象都读入HashMap中,然后使用普通的assertEquals()方法进行比较。它会调用hashmaps的equals()方法,该方法将递归地比较内部的所有对象(它们将是其他hashmaps或一些单值对象,如字符串或整数)。这是使用Codehaus' Jackson JSON解析器完成的。
assertEquals(mapper.readValue(expectedJson, new TypeReference<HashMap<String, Object>>(){}), mapper.readValue(actualJson, new TypeReference<HashMap<String, Object>>(){}));
如果JSON对象是数组,则可以使用类似的方法。
toString()
将对象转换为JSON
字符串。 - Teja Kantamneni