Estou procurando uma biblioteca de análise JSON que suporte a comparação de dois objetos JSON que ignoram a ordem dos filhos, especificamente para testar a unidade JSON retornando de um serviço da web.
Alguma das principais bibliotecas JSON suporta isso? A biblioteca org.json simplesmente faz uma comparação de referência.
toString()
para converter o objeto emJSON
string.Respostas:
Como ponto de arquitetura geral, geralmente não aconselho a deixar dependências em um formato de serialização específico ir além da camada de armazenamento / rede; portanto, primeiro recomendo que você considere testar a igualdade entre seus próprios objetos de aplicativo em vez de suas manifestações JSON.
Dito isto, atualmente sou um grande fã de Jackson, o que minha leitura rápida da implementação de ObjectNode.equals () sugere que a comparação de associação definida que você deseja:
fonte
Experimente o JSONAssert do Skyscreamer .
Seu modo não estrito possui duas vantagens principais que o tornam menos quebradiço:
No modo estrito, ele se comporta mais como a classe de teste do json-lib.
Um teste é mais ou menos assim:
Os parâmetros na chamada JSONAssert.assertEquals () são esperado : JSONString , actualDataString e isStrict .
As mensagens de resultado são bastante claras, o que é importante ao comparar objetos JSON realmente grandes.
fonte
JSONAssert.assertEquals(expected, data, JSONCompareMode.NON_EXTENSIBLE);
O modo NON_EXTENSIBLE significa que qualquer campo novo ou ausente causa falhas, mas o pedido não. O uso de false instigaria o modo branda, que não relataria nenhum elemento filho extra ou ausente.Usando o GSON
Edit: Desde o GSON v2.8.6, o método da instância
JsonParser.parse
está obsoleto. Você precisa usar o método estáticoJsonParser.parseString
:fonte
Eu faria o seguinte,
fonte
Você pode tentar usar a classe JSONAssert do json-lib :
Dá:
fonte
JSONAssert.assertJsonEquals( "{foo: 'bar', list: [{test: '1'}, {rest: '2'}] }", "{ foo: 'bar', list: [{rest: '2'}, {test: '1'}] }");
Com a mensagem: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 a ordem nas matrizes
fonte
Se você já está usando o JUnit, a versão mais recente agora emprega o Hamcrest. É uma estrutura de correspondência genérica (especialmente útil para testes de unidade) que pode ser estendida para criar novos correspondentes.
Há uma pequena biblioteca de código aberto chamada
hamcrest-json
com correspondências compatíveis com JSON. Está bem documentado, testado e suportado. Abaixo estão alguns links úteis:Código de exemplo usando objetos da biblioteca JSON
org.json.simple
:Opcionalmente, você pode (1) permitir matrizes de "qualquer ordem" e (2) ignorar campos extras.
Uma vez que há uma variedade de bibliotecas JSON para Java (
Jackson
,GSON
,json-lib
, etc.), é útil quehamcrest-json
o texto suportes JSON (comojava.lang.String
), objetos, bem como nativamente suporte da biblioteca JSON de Douglas Crockfordorg.json
.Por fim, se você não estiver usando o JUnit, poderá usar o Hamcrest diretamente para asserções. ( Eu escrevi sobre isso aqui. )
fonte
Você pode tentar o JsonUnit . Pode comparar dois objetos JSON e relatar diferenças. É construído em cima de Jackson.
Por exemplo
Resulta em
fonte
Uma coisa que fiz e faz maravilhas é ler os dois objetos no HashMap e comparar com um assertEquals () regular. Ele chamará o método equals () dos hashmaps, que comparará recursivamente todos os objetos internos (eles serão outros hashmaps ou algum objeto de valor único, como uma string ou um número inteiro). Isso foi feito usando o analisador Jackson JSON da Codehaus.
Uma abordagem semelhante pode ser usada se o objeto JSON for uma matriz.
fonte
Estou usando isso e funciona bem para mim (com org.json. *):
fonte
Para org.json, implantei minha própria solução, um método que se compara às instâncias JSONObject. Como não trabalhei com objetos JSON complexos nesse projeto, não sei se isso funciona em todos os cenários. Além disso, como utilizo isso em testes de unidade, não dediquei esforços às otimizações. Aqui está:
fonte
val1
é nulo você receberá um NullPointerException deste códigoif (!val1.equals(val2)) {
js2
énull
ou não quandojs1
não énull
Você pode usar a biblioteca zjsonpatch , que apresenta as informações diferenciais de acordo com o RFC 6902 (JSON Patch). É muito fácil de usar. Por favor, visite sua página de descrição para seu uso
fonte
Eu pegaria a biblioteca em http://json.org/java/ e modificaria o
equals
método JSONObject e JSONArray para fazer um teste de igualdade profunda. Para garantir que ele funcione sem ordem de ordem dos filhos, tudo o que você precisa fazer é substituir o mapa interno por aTreeMap
ou usar algo parecidoCollections.sort()
.fonte
Tente o seguinte:
fonte
if (obj1Array.length() != obj2Array.length())
não garante que todos os elementos coincidam?Sei que geralmente é considerado apenas para teste, mas você poderia usar o Hamcrest JSON comparatorSameJSONAs no Hamcrest JSON.
Hamcrest JSON SameJSONAs
fonte
Karatê é exatamente o que você está procurando. Aqui está um exemplo:
(aviso: dev aqui)
fonte
Para comparar jsons, recomendo usar o JSONCompare: https://github.com/fslev/json-compare
fonte
Para aqueles como eu que querem fazer isso com Jackson, você pode usar o json-unit .
Os erros fornecem feedback útil sobre o tipo de incompatibilidade:
fonte
Nada mais parecia funcionar muito bem, então eu escrevi o seguinte:
fonte
O código a seguir será mais útil para comparar dois JsonObject, JsonArray, JsonPrimitive e JasonElements.
fonte
https://tech.blobcity.com/2018/09/02/json-equals-in-java-to-compare-two-jsons
fonte
Olhando para as respostas, tentei o JSONAssert, mas ele falhou. Então, eu usei Jackson com zjsonpatch. Postei detalhes na resposta SO aqui .
fonte
Esta solução para mim, o trabalho é muito bom:
Espero que isso ajude os outros.
fonte