Estoy buscando una biblioteca de análisis JSON que admita la comparación de dos objetos JSON ignorando el orden secundario, 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 referencia.
toString()
convertir el objeto enJSON
cadena.Respuestas:
Como un punto arquitectónico general, generalmente aconsejo no permitir que las dependencias en un formato de serialización particular se desvanezcan más allá de su capa de almacenamiento / red; por lo tanto, primero recomendaría que considere probar la igualdad entre sus propios objetos de 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 ObjectNode.equals () sugiere la comparación de membresía establecida que desea:
fuente
Prueba el JSONAssert de Skyscreamer .
Su modo no estricto tiene dos ventajas principales que lo hacen menos frágil:
En modo estricto, se comporta más como la clase de prueba de json-lib.
Una prueba se parece a esto:
Los parámetros de los JSONAssert.assertEquals () llamada se expectedJSONString , actualDataString y isStrict .
Los mensajes de resultados son bastante claros, lo cual es importante cuando se comparan objetos JSON realmente grandes.
fuente
JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);
el modo NON_EXTENSIBLE significa que los campos nuevos o faltantes causan fallas, pero el orden no. El uso de falso instigaría el modo indulgente que no informaría ningún elemento secundario extra o faltante.Usando GSON
Editar: desde GSON v2.8.6, el método de instancia
JsonParser.parse
está en desuso. Tienes que usar el método estáticoJsonParser.parseString
:fuente
Yo haría lo siguiente,
fuente
Puede intentar usar la clase JSONAssert de json-lib :
Da:
fuente
JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }");
Con el mensaje:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Use esta biblioteca: https://github.com/lukas-krecan/JsonUnit
Pom:
IGNORING_ARRAY_ORDER: ignora el orden en las matrices
fuente
Si ya está utilizando JUnit, la última versión ahora emplea Hamcrest. Es un marco genérico de coincidencia (especialmente útil para pruebas unitarias) que se puede ampliar para crear nuevos emparejadores.
Hay una pequeña biblioteca de código abierto llamada
hamcrest-json
con coincidencias compatibles con JSON. Está bien documentado, probado y respaldado. A continuación hay algunos enlaces útiles:Código de ejemplo usando objetos de la biblioteca JSON
org.json.simple
:Opcionalmente, puede (1) permitir matrices de "cualquier orden" e (2) ignorar campos adicionales.
Puesto que hay una variedad de bibliotecas JSON para Java (
Jackson
,GSON
,json-lib
, etc.), es útil quehamcrest-json
el texto JSON soportes (comojava.lang.String
), los objetos, así como de forma nativa soporte de la biblioteca JSON de Douglas Crockfordorg.json
.Finalmente, si no está usando JUnit, puede usar Hamcrest directamente para afirmaciones. ( Escribí sobre esto aquí ) .
fuente
Puedes probar JsonUnit . Puede comparar dos objetos JSON e informar diferencias. Está construido encima de Jackson.
Por ejemplo
Resultados en
fuente
Una cosa que hice y que funciona de maravilla es leer ambos objetos en HashMap y luego compararlos con un aserciónEquals () regular. Llamará al método equals () de los hashmaps, que comparará recursivamente todos los objetos dentro (serán otros hashmaps o algún objeto de valor único como una cadena o un entero). Esto se hizo usando el analizador Jackson JSON de Codehaus.
Se puede usar un enfoque similar si el objeto JSON es una matriz en su lugar.
fuente
Estoy usando esto, y funciona bien para mí (con org.json. *):
fuente
Para org.json, implementé mi propia solución, un método que se compara con las instancias de JSONObject. No trabajé con objetos JSON complejos en ese proyecto, por lo que no sé si esto funciona en todos los escenarios. Además, dado que uso esto en pruebas unitarias, no puse esfuerzo en las optimizaciones. Aquí está:
fuente
val1
es nulo, obtendrá un NullPointerException de este códigoif (!val1.equals(val2)) {
js2
esnull
o no cuandojs1
no lo esnull
Puede usar la biblioteca zjsonpatch , que presenta la información de diferencias de acuerdo con RFC 6902 (parche JSON). Es muy fácil de usar. Visite su página de descripción para su uso.
fuente
Tomaría la biblioteca en http://json.org/java/ , y modificaría el
equals
método de JSONObject y JSONArray para hacer una prueba de igualdad profunda. Para asegurarse de que funciona sin graduación del orden de los hijos, todo lo que necesita hacer es reemplazar el mapa interno con aTreeMap
, o usar algo comoCollections.sort()
.fuente
Prueba esto:
fuente
if (obj1Array.length() != obj2Array.length())
no garantiza que todos los elementos coincidan?Sé que por lo general sólo se considera para la prueba pero se puede usar la Hamcrest JSON comparitorSameJSONAs en Hamcrest JSON.
Hamcrest JSON SameJSONAs
fuente
Karate es exactamente lo que estás buscando. Aquí hay un ejemplo:
(descargo de responsabilidad: dev aquí)
fuente
Para comparar jsons, recomiendo usar JSONCompare: https://github.com/fslev/json-compare
fuente
Para aquellos como yo que quieran hacer esto con Jackson, pueden usar json-unit .
Los errores brindan comentarios útiles sobre el tipo de desajuste:
fuente
Nada más parecía funcionar bien, así que escribí esto:
fuente
El siguiente código será más útil para comparar dos JsonObject, JsonArray, JsonPrimitive y JasonElements.
fuente
https://tech.blobcity.com/2018/09/02/json-equals-in-java-to-compare-two-jsons
fuente
Mirando las respuestas, probé JSONAssert pero falló. Así que usé Jackson con zjsonpatch. Publiqué detalles en la respuesta SO aquí .
fuente
Esta solución para mí, el trabajo es muy bueno:
Espero que esto ayude a otros.
fuente