2016-08-09 25 views
5

Ich möchte zwei JSON-Strings vergleichen, die eine riesige Hierarchie darstellen und wissen wollen, wo sie sich in Werten unterscheiden. Einige Werte werden jedoch zur Laufzeit generiert und sind dynamisch. Ich möchte diese bestimmten Knoten aus meinem Vergleich ignorieren.Ignoriere bestimmte Knoten/Attribute beim Vergleich zweier JSONs

Ich verwende derzeit JSONAssert von org.SkyScreamer, um den Vergleich zu tun. Es gibt mir eine schöne Konsolenausgabe, ignoriert aber keine Attribute.

für ex.

java.lang.AssertionError messageHeader.sentTime 
expected:null 
got:09082016 18:49:41.123 

Jetzt kommt das dynamisch und sollte ignoriert werden. So etwas wie

JSONAssert.assertEquals(expectedJSONString, actualJSONString,JSONCompareMode, *list of attributes to be ignored*) 

Es wäre toll, wenn jemand eine Lösung in JSONAssert vermuten lässt. Andere Wege sind jedoch auch willkommen.

+0

Was passiert, wenn Sie JSONCompareMode als false angeben? ignoriert es die Knoten nicht? –

+0

@ rishal-dev-singh Nein, spezifische Attribute werden nicht ignoriert – Prateik

+0

@Pratik Als Alternative können Sie die Attribute vor dem Vergleich entfernen. Als eine weitere Alternative können Sie es selbst tun, z. http://stackoverflow.com/questions/2253750/compare-two-json-objects-in-java –

Antwort

2

Sie können Anpassung für diese verwenden.

JSONAssert.assertEquals(expectedResponseBody, responseBody, 
      new CustomComparator(JSONCompareMode.LENIENT, 
       new Customization("timestamp", (o1, o2) -> true))); 

Es ist auch möglich, Pfadausdrücke wie „entry.id“ zu verwenden: Zum Beispiel, wenn Sie ein Top-Level-Attribut mit dem Namen „Zeitstempel“ Verwendung ignorieren müssen. In Ihrer Anpassung können Sie die gewünschte Methode verwenden, um die beiden Werte zu vergleichen. Das obige Beispiel gibt immer true zurück, unabhängig vom erwarteten Wert und vom tatsächlichen Wert. Sie könnten dort kompliziertere Sachen machen, wenn Sie müssen.

0

Zuerst gibt es open issue dafür.

In meinen Tests zu vergleichen, ich json von der Steuerung mit dem tatsächlichen Objekt mit Hilfe von JsonUtil Klasse für die Serialisierung/Deserialisierung:

public class JsonUtil { 
    public static <T> List<T> readValues(String json, Class<T> clazz) { 
     ObjectReader reader = getMapper().readerFor(clazz); 
     try { 
      return reader.<T>readValues(json).readAll(); 
     } catch (IOException e) { 
      throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e); 
     } 
    } 

    public static <T> T readValue(String json, Class<T> clazz) { 
     try { 
      return getMapper().readValue(json, clazz); 
     } catch (IOException e) { 
      throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e); 
     } 
    } 

    public static <T> String writeValue(T obj) { 
     try { 
      return getMapper().writeValueAsString(obj); 
     } catch (JsonProcessingException e) { 
      throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e); 
     } 
    } 

spezifisches Objektfeld ignorieren ich neue Methode hinzufügen habe:

public static <T> String writeIgnoreProps(T obj, String... ignoreProps) { 
    try { 
     Map<String, Object> map = getMapper().convertValue(obj, new TypeReference<Map<String, Object>>() {}); 
     for (String prop : ignoreProps) { 
      map.remove(prop); 
     } 
     return getMapper().writeValueAsString(map); 
    } catch (JsonProcessingException e) { 
     throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e); 
    } 
} 

und meine assert in Test sehen nun wie folgt aus:

  mockMvc.perform(get(REST_URL)) 
      .andExpect(status().isOk()) 
      .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) 
      .andExpect(content().json(JsonUtil.writeIgnoreProps(USER, "registered"))) 
-1

Sie können verwenden JsonUnit Es hat die Funktionalität, die Sie suchen, können wir Felder, Pfade und Werte, die Null usw. ignorieren, überprüfen Sie es für weitere Informationen. Wie für das Beispiel, können Sie den Pfad so

assertJsonEquals(
    "{\"root\":{\"test\":1, \"ignored\": 2}}", 
    "{\"root\":{\"test\":1, \"ignored\": 1}}", 
    whenIgnoringPaths("root.ignored") 
); 

ignorieren Manchmal müssen Sie bestimmte Werte ignorieren beim Vergleich. Es ist möglich, $ {json-unit.ignore} Platzhalter wie dieses zu verwenden

assertJsonEquals("{\"test\":\"${json-unit.ignore}\"}", 
    "{\n\"test\": {\"object\" : {\"another\" : 1}}}"); 
+0

Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz zur Verfügung zu stellen.Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - [Aus Bewertung] (/ review/low-quality-posts/18596505) – NewUser

Verwandte Themen