I want to compare two JSON strings in Java 8 for equality, but ignore specific known nodes which contain values which are expected to be different and are a tolerated difference e.g. timestamp. Currently using JSONAssert v1.5.0 from org.SkyScreamer, I’m able to ‘ignore’ a number of these nodes, but cannot ‘ignore’ nodes within an array.
What I would like is to extend my current JSONComparator to include a Customization which has its first ‘path’ parameter having an array address.
JSONComparator customisedJobComparator = new CustomComparator(JSONCompareMode.NON_EXTENSIBLE, new Customization("id", (o1, o2) -> true), new Customization("appointmentBookedDate.$date", (o1, o2) -> true), ... new Customization("someArray[n].timestamp", (o1, o2) -> true) //<--- this is wrong, what is the correct way for this path address? );
The code below is my attempt at proving a solution; both expected/actual JSON strings are identical except for anArray[].id values. I want this test to pass, but is failing with error: java.lang.AssertionError: anArray[0] Could not find match for element {“id”:”valueA”}
@Test public void compareJsonStrIgnoringDiffInArray() { String errorMsg = ""; String expectedJsonStr = "{"anArray": [{"id": "valueA"}, {"colour": "Blue"}]}"; String actualJsonStr = "{"anArray": [{"id": "valueB"}, {"colour": "Blue"}]}"; //Create custom comparator which compares two json strings but ignores reporting any differences for anArray[n].id values //as they are a tolerated difference Customization customization = new Customization("anArray[n].id", (o1, o2) -> true); JSONComparator customisedComparator = new CustomComparator(JSONCompareMode.NON_EXTENSIBLE, customization); JSONAssert.assertEquals(errorMsg, expectedJsonStr, actualJsonStr, customisedComparator); }
Advertisement
Answer
After some digging in the javadoc for JSONAssert, I saw an example that used an array of objects. From that example I was able to modify your test case:
@Test public void compareJsonStrIgnoringDiffInArray() throws JSONException { String errorMsg = ""; String expectedJsonStr = "{"anArray": [{"id": "valueA"}, {"colour": "Blue"}]}"; String actualJsonStr = "{"anArray": [{"id": "valueB"}, {"colour": "Blue"}]}"; //Create custom comparator which compares two json strings but ignores reporting any differences for anArray[n].id values //as they are a tolerated difference ArrayValueMatcher<Object> arrValMatch = new ArrayValueMatcher<>(new CustomComparator( JSONCompareMode.NON_EXTENSIBLE, new Customization("anArray[*].id", (o1, o2) -> true))); Customization arrayValueMatchCustomization = new Customization("anArray", arrValMatch); CustomComparator customArrayValueComparator = new CustomComparator( JSONCompareMode.NON_EXTENSIBLE, arrayValueMatchCustomization); JSONAssert.assertEquals(expectedJsonStr, actualJsonStr, customArrayValueComparator); }