Probando la igualdad de dos objetos JSON ignorando el orden de los hijos en Java [cerrado]
Estoy buscando una biblioteca de análisis JSON que admita la comparación de dos objetos JSON ignorando el orden de los hijos, específicamente para pruebas unitarias de JSON que regresan de un servicio web.
¿Alguna de las principales bibliotecas JSON admite esto? La biblioteca org.json simplemente hace una comparación de referencias.
Pruebe JSONAssert de Skyscreamer .
Su modo no estricto tiene dos grandes ventajas que lo hacen menos frágil:
- Extensibilidad del objeto (por ejemplo, con un valor esperado de {id:1} , esto aún pasaría: {id:1,moredata:'x'} ).
- Orden de matriz suelta (por ejemplo, ['perro','gato']==['gato','perro'])
En modo estricto, se comporta más como la clase de prueba de json-lib.
Una prueba se parece a esto:
@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);
}
Los parámetros en la llamada JSONAssert.assertEquals() son expectJSONString , actualDataString e isStrict .
Los mensajes de resultados son bastante claros, lo cual es importante cuando se comparan objetos JSON realmente grandes.
Como punto arquitectónico general, normalmente desaconsejo dejar que las dependencias de un formato de serialización particular se extiendan más allá de su capa de almacenamiento/red; por lo tanto, primero recomendaría que considere probar la igualdad entre los objetos de su propia aplicación en lugar de sus manifestaciones JSON.
Dicho esto, actualmente soy un gran admirador de Jackson y mi lectura rápida de su implementación de ObjectNode.equals() sugiere que hace la comparación de membresía establecida que desea:
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;
}
Usando 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);
Editar: desde GSON v2.8.6, el método de instancia JsonParser.parse
está en desuso. Tienes que usar el método estático JsonParser.parseString
:
JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);
Yo haría lo siguiente,
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);