Testing two JSON objects for equality ignoring child order in Java Testing two JSON objects for equality ignoring child order in Java json json

Testing two JSON objects for equality ignoring child order in Java

Try Skyscreamer's JSONAssert.

Its non-strict mode has two major advantages that make it less brittle:

  • Object extensibility (e.g. With an expected value of {id:1}, this would still pass: {id:1,moredata:'x'}.)
  • Loose array ordering (e.g. ['dog','cat']==['cat','dog'])

In strict mode it behaves more like json-lib's test class.

A test looks something like this:

@Testpublic 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);}

The parameters in the JSONAssert.assertEquals() call are expectedJSONString, actualDataString, and isStrict.

The result messages are pretty clear, which is important when comparing really big JSON objects.

As a general architectural point, I usually advise against letting dependencies on a particular serialization format bleed out beyond your storage/networking layer; thus, I'd first recommend that you consider testing equality between your own application objects rather than their JSON manifestations.

Having said that, I'm currently a big fan of Jackson which my quick read of their ObjectNode.equals() implementation suggests does the set membership comparison that you want:

public 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;}

Using 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);

Edit: Since GSON v2.8.6 the instance method JsonParser.parse is deprecated. You have to use the static method JsonParser.parseString:

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