Ich suche nach einer JSON-Analysebibliothek, die das Vergleichen von zwei JSON-Objekten unterstützt, bei denen die untergeordnete Reihenfolge ignoriert wird, insbesondere zum Testen von JSON-Einheiten, die von einem Webdienst zurückkehren.
Unterstützt eine der wichtigsten JSON-Bibliotheken dies? Die org.json-Bibliothek führt einfach einen Referenzvergleich durch.
toString()
das Konvertieren des Objekts in einenJSON
String.Antworten:
Als allgemeiner architektonischer Punkt rate ich normalerweise davon ab, Abhängigkeiten von einem bestimmten Serialisierungsformat über Ihre Speicher- / Netzwerkschicht hinaus ausbluten zu lassen. Daher würde ich zunächst empfehlen, die Gleichheit zwischen Ihren eigenen Anwendungsobjekten und nicht deren JSON-Manifestationen zu testen.
Trotzdem bin ich derzeit ein großer Fan von Jackson, was meine schnelle Lektüre der ObjectNode.equals () -Implementierung nahe legt, dass der von Ihnen gewünschte Vergleich der festgelegten Mitgliedschaft durchgeführt wird:
quelle
Probieren Sie JSONAssert von Skyscreamer aus .
Sein nicht strenger Modus hat zwei Hauptvorteile, die ihn weniger spröde machen:
Im strengen Modus verhält es sich eher wie die Testklasse von json-lib.
Ein Test sieht ungefähr so aus:
Die Parameter im Aufruf von JSONAssert.assertEquals () sind erwartetJSONString , actualDataString und isStrict .
Die Ergebnismeldungen sind ziemlich klar, was beim Vergleich wirklich großer JSON-Objekte wichtig ist.
quelle
JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);
ungefähr Folgendes : Der Modus NON_EXTENSIBLE bedeutet, dass neue oder fehlende Felder Fehler verursachen, die Reihenfolge jedoch nicht. Die Verwendung von false würde einen milden Modus auslösen, der keine zusätzlichen oder fehlenden untergeordneten Elemente meldet.Verwenden von GSON
Bearbeiten: Seit GSON v2.8.6 ist die Instanzmethode
JsonParser.parse
veraltet. Sie müssen die statische Methode verwendenJsonParser.parseString
:quelle
Ich würde folgendes tun:
quelle
Sie können versuchen, die JSONAssert- Klasse von json-lib zu verwenden :
Gibt:
quelle
JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }");
Mit der Nachricht:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Verwenden Sie diese Bibliothek: https://github.com/lukas-krecan/JsonUnit
Pom:
IGNORING_ARRAY_ORDER - ignoriert die Reihenfolge in Arrays
quelle
Wenn Sie JUnit bereits verwenden, wird in der neuesten Version jetzt Hamcrest verwendet. Es ist ein generisches Matching-Framework (besonders nützlich für Unit-Tests), das erweitert werden kann, um neue Matcher zu erstellen.
Es gibt eine kleine Open-Source-Bibliothek
hamcrest-json
mit JSON-fähigen Übereinstimmungen. Es ist gut dokumentiert, getestet und unterstützt. Unten finden Sie einige nützliche Links:Beispielcode mit Objekten aus der JSON-Bibliothek
org.json.simple
:Optional können Sie (1) Arrays beliebiger Reihenfolge zulassen und (2) zusätzliche Felder ignorieren.
Da es eine Vielzahl von JSON-Bibliotheken für Java gibt (
Jackson
,GSON
,json-lib
, etc.), ist es sinnvoll , dasshamcrest-json
Träger JSON Text (wiejava.lang.String
) sowie native Objekte von Douglas Crockford JSON - Bibliothek unterstütztorg.json
.Wenn Sie JUnit nicht verwenden, können Sie Hamcrest direkt für Zusicherungen verwenden. ( Ich habe hier darüber geschrieben. )
quelle
Sie können JsonUnit ausprobieren . Es kann zwei JSON-Objekte vergleichen und Unterschiede melden. Es ist auf Jackson gebaut.
Beispielsweise
Ergebnisse in
quelle
Eine Sache, die ich getan habe und die Wunder wirkt, ist, beide Objekte in HashMap einzulesen und dann mit einem regulären assertEquals () zu vergleichen. Es wird die equals () -Methode der Hashmaps aufgerufen, die alle darin enthaltenen Objekte rekursiv vergleicht (es handelt sich entweder um andere Hashmaps oder um ein Einzelwertobjekt wie eine Zeichenfolge oder eine Ganzzahl). Dies wurde mit dem Jackson JSON-Parser von Codehaus durchgeführt.
Ein ähnlicher Ansatz kann verwendet werden, wenn das JSON-Objekt stattdessen ein Array ist.
quelle
Ich benutze dies und funktioniert gut für mich (mit org.json. *):
quelle
Für org.json habe ich meine eigene Lösung eingeführt, eine Methode, die mit JSONObject-Instanzen verglichen wird. Ich habe in diesem Projekt nicht mit komplexen JSON-Objekten gearbeitet, daher weiß ich nicht, ob dies in allen Szenarien funktioniert. Da ich dies in Unit-Tests verwende, habe ich mich auch nicht um Optimierungen bemüht. Hier ist es:
quelle
val1
null ist, erhalten Sie eine NullPointerException von diesem Codeif (!val1.equals(val2)) {
js2
istnull
oder nicht, wannjs1
nichtnull
Sie können die zjsonpatch- Bibliothek verwenden, die die Diff-Informationen gemäß RFC 6902 (JSON-Patch) darstellt. Es ist sehr einfach zu bedienen. Bitte besuchen Sie die Beschreibungsseite für die Verwendung
quelle
Ich würde die Bibliothek unter http://json.org/java/ nehmen und die
equals
Methode von JSONObject und JSONArray ändern, um einen tiefen Gleichheitstest durchzuführen. Um sicherzustellen, dass es unabhängig von der Reihenfolge der Kinder funktioniert, müssen Sie lediglich die innere Karte durch eine ersetzenTreeMap
oder etwas Ähnliches verwendenCollections.sort()
.quelle
Versuche dies:
quelle
if (obj1Array.length() != obj2Array.length())
nicht sicher, dass alle Elemente übereinstimmen?Ich weiß, dass es normalerweise nur zum Testen in Betracht gezogen wird, aber Sie könnten den Hamcrest JSON- KomparatorSameJSONAs in Hamcrest JSON verwenden.
Hamcrest JSON SameJSONAs
quelle
Karate ist genau das, wonach Sie suchen. Hier ist ein Beispiel:
(Haftungsausschluss: dev hier)
quelle
Zum Vergleichen von jsons empfehle ich die Verwendung von JSONCompare: https://github.com/fslev/json-compare
quelle
Für diejenigen wie mich, die dies mit Jackson machen wollen, können Sie json-unit verwenden .
Die Fehler geben nützliche Rückmeldungen zur Art der Nichtübereinstimmung:
quelle
Nichts anderes schien ganz richtig zu funktionieren, also schrieb ich Folgendes:
quelle
Der folgende Code ist hilfreicher, um zwei JsonObject, JsonArray, JsonPrimitive und JasonElements zu vergleichen.
quelle
https://tech.blobcity.com/2018/09/02/json-equals-in-java-to-compare-two-jsons
quelle
Als ich mir die Antworten ansah, versuchte ich es mit JSONAssert, aber es schlug fehl. Also habe ich Jackson mit zjsonpatch benutzt. Ich habe Details in der SO-Antwort hier gepostet .
quelle
Diese Lösung ist für mich sehr gut:
Hoffe das hilft anderen.
quelle