Szukam biblioteki analizującej JSON, która obsługuje porównywanie dwóch obiektów JSON ignorujących kolejność elementów podrzędnych, szczególnie do testowania jednostkowego JSON powracającego z usługi WWW.
Czy którakolwiek z głównych bibliotek JSON obsługuje to? Biblioteka org.json po prostu porównuje odniesienia.
toString()
konwersję obiektu naJSON
ciąg.Odpowiedzi:
Jako ogólny punkt architektoniczny zwykle odradzam uwalnianie zależności od określonego formatu serializacji poza warstwę pamięci / sieci; dlatego najpierw zaleciłbym rozważenie przetestowania równości między własnymi obiektami aplikacji, a nie ich manifestacjami JSON.
Powiedziawszy to, jestem obecnie wielkim fanem Jacksona, który mój szybki odczyt ich implementacji ObjectNode.equals () sugeruje, czy zestaw porównawczy członkostwa, który chcesz:
źródło
Wypróbuj JSONAssert w Skyscreamer .
Jego zakaz ścisłe tryb ma dwie główne zalety, które czynią go mniej kruche:
W trybie ścisłym zachowuje się bardziej jak klasa testowa json-lib.
Test wygląda mniej więcej tak:
Parametry w wywołaniu JSONAssert.assertEquals () są oczekiwane : JSONString , actualDataString i isStrict .
Komunikaty wyników są dość wyraźne, co jest ważne przy porównywaniu naprawdę dużych obiektów JSON.
źródło
JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);
Tryb NON_EXTENSIBLE oznacza, że wszelkie nowe lub brakujące pola powodują awarie, ale kolejność nie. Użycie false spowoduje uruchomienie trybu łagodnego, który nie zgłosi żadnych dodatkowych lub brakujących elementów potomnych.Korzystanie z GSON
Edycja: Od wersji GSON v2.8.6 metoda instancji
JsonParser.parse
jest przestarzała. Musisz użyć metody statycznejJsonParser.parseString
:źródło
Zrobiłbym następujące,
źródło
Możesz spróbować użyć klasy JSONAssert json-lib :
Daje:
źródło
JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }");
Komunikat:junit.framework.AssertionFailedError: : : objects differed at key [list];: arrays first differed at element [0];: objects differed at key [test];
Użyj tej biblioteki: https://github.com/lukas-krecan/JsonUnit
Pom:
IGNORING_ARRAY_ORDER - ignoruje kolejność w tablicach
źródło
Jeśli już używasz JUnit, najnowsza wersja zawiera teraz Hamcrest. Jest to ogólna struktura dopasowywania (szczególnie przydatna do testowania jednostkowego), którą można rozszerzyć w celu zbudowania nowych dopasowań.
Istnieje mała biblioteka open source o nazwie
hamcrest-json
z dopasowaniami JSON. Jest dobrze udokumentowany, przetestowany i obsługiwany. Poniżej znajdują się przydatne linki:Przykładowy kod wykorzystujący obiekty z biblioteki JSON
org.json.simple
:Opcjonalnie możesz (1) zezwolić na tablice „dowolnego rzędu” i (2) zignorować dodatkowe pola.
Ponieważ istnieje wiele bibliotek JSON for Java (
Jackson
,GSON
,json-lib
, itd), jest przydatna, żehamcrest-json
tekst podpory JSON (jakjava.lang.String
), a także obiekty wspierające natywnie z JSON biblioteki Douglasa Crockforda użytkownikaorg.json
.Wreszcie, jeśli nie używasz JUnit, możesz użyć Hamcrest bezpośrednio do asercji. ( Pisałem o tym tutaj. )
źródło
Możesz wypróbować JsonUnit . Może porównywać dwa obiekty JSON i zgłaszać różnice. Jest zbudowany na Jacksonie.
Na przykład
Prowadzi do
źródło
Jedną rzeczą, którą zrobiłem i działa cuda, jest odczytanie obu obiektów do HashMap, a następnie porównanie ze zwykłą funkcją assertEquals (). Wywoła metodę haszaps równą (), która rekurencyjnie porównuje wszystkie obiekty w środku (będą to albo inne haszapy, albo jakiś obiekt o pojedynczej wartości, taki jak łańcuch lub liczba całkowita). Dokonano tego przy użyciu analizatora składni JSON firmy Codehaus.
Podobne podejście można zastosować, jeśli obiekt JSON jest tablicą.
źródło
Używam tego i działa dobrze dla mnie (z org.json. *):
źródło
W przypadku org.json wdrożyłem własne rozwiązanie, metodę porównywalną z instancjami JSONObject. W tym projekcie nie pracowałem ze złożonymi obiektami JSON, więc nie wiem, czy to działa we wszystkich scenariuszach. Biorąc pod uwagę, że używam tego w testach jednostkowych, nie wkładałem wysiłku w optymalizacje. Oto on:
źródło
val1
jest null, otrzymasz wyjątek NullPointerException z tego koduif (!val1.equals(val2)) {
js2
jest,null
czy nie, kiedyjs1
nie manull
Możesz użyć biblioteki zjsonpatch , która przedstawia informacje o różnicach zgodnie z RFC 6902 (łatka JSON). Jest bardzo łatwy w użyciu. Proszę odwiedzić jego stronę z opisem użycia
źródło
Wziąłbym bibliotekę pod adresem http://json.org/java/ i zmodyfikowałem
equals
metodę JSONObject i JSONArray, aby przeprowadzić głęboki test równości. Aby upewnić się, że działa bez względu na kolejność dzieci, wystarczy wymienić wewnętrzną mapę naTreeMap
lub użyć czegoś podobnegoCollections.sort()
.źródło
Spróbuj tego:
źródło
if (obj1Array.length() != obj2Array.length())
nie gwarantuje, że wszystkie elementy się pokrywają?Wiem, że to jest zwykle uważane tylko do testów, ale można użyć Hamcrest JSON comparitorSameJSONAs w Hamcrest JSON.
Hamcrest JSON SameJSONAs
źródło
Karate jest dokładnie tym, czego szukasz. Oto przykład:
(wyłączenie odpowiedzialności: tutaj programista)
źródło
Do porównania jsonów polecam użycie JSONCompare: https://github.com/fslev/json-compare
źródło
Dla takich jak ja, którzy chcą to zrobić z Jacksonem, możesz użyć json-unit .
Błędy dają użyteczne informacje zwrotne na temat rodzaju niedopasowania:
źródło
Nic innego nie działało całkiem dobrze, więc napisałem to:
źródło
Poniższy kod będzie bardziej pomocny w porównaniu dwóch JsonObject, JsonArray, JsonPrimitive i JasonElements.
źródło
https://tech.blobcity.com/2018/09/02/json-equals-in-java-to-compare-two-jsons
źródło
Patrząc na odpowiedzi, spróbowałem JSONAssert, ale nie udało się. Więc użyłem Jacksona z zjsonpatch. Podałem szczegóły w odpowiedzi SO tutaj .
źródło
To rozwiązanie jest dla mnie bardzo dobre:
Mam nadzieję, że pomoże to innym.
źródło