在比较两个JSON时忽略特定节点/属性
我想比较两个JSON字符串,这是一个巨大的层次结构,并想知道它们在值上的不同之处。 但是某些值是在运行时生成的并且是动态的。 我想忽略我比较中的那些特定节点。
我目前正在使用org.SkyScreamer的JSONAssert进行比较。 它给了我很好的控制台输出但不忽略任何属性。
对于前
java.lang.AssertionError messageHeader.sentTime expected:null got:09082016 18:49:41.123
现在这是动态的,应该被忽略。 就像是
JSONAssert.assertEquals(expectedJSONString, actualJSONString,JSONCompareMode, *list of attributes to be ignored*)
如果有人在JSONAssert中建议解决方案,那就太好了。 然而,其他方式也是受欢迎的。
您可以使用自定义。 例如,如果您需要忽略名为“timestamp”的顶级属性,请使用:
JSONAssert.assertEquals(expectedResponseBody, responseBody, new CustomComparator(JSONCompareMode.LENIENT, new Customization("timestamp", (o1, o2) -> true)));
也可以使用像“entry.id”这样的路径表达式。 在您的自定义中,您可以使用您喜欢的任何方法来比较这两个值。 无论期望值和实际值是什么,上面的示例始终返回true。 如果需要,你可以在那里做更复杂的事情。
首先,它存在未解决的问题 。
在我的测试中,我将json从控制器与实际对象进行比较,并在JsonUtil
类的帮助下进行序列化/反序列化:
public class JsonUtil { public static List readValues(String json, Class clazz) { ObjectReader reader = getMapper().readerFor(clazz); try { return reader. readValues(json).readAll(); } catch (IOException e) { throw new IllegalArgumentException("Invalid read array from JSON:\n'" + json + "'", e); } } public static T readValue(String json, Class clazz) { try { return getMapper().readValue(json, clazz); } catch (IOException e) { throw new IllegalArgumentException("Invalid read from JSON:\n'" + json + "'", e); } } public static String writeValue(T obj) { try { return getMapper().writeValueAsString(obj); } catch (JsonProcessingException e) { throw new IllegalStateException("Invalid write to JSON:\n'" + obj + "'", e); } }
要忽略特定的对象字段,我添加了新方法:
public static String writeIgnoreProps(T obj, String... ignoreProps) { try { Map map = getMapper().convertValue(obj, new TypeReference
而我在测试中的断言现在看起来像这样:
mockMvc.perform(get(REST_URL)) .andExpect(status().isOk()) .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) .andExpect(content().json(JsonUtil.writeIgnoreProps(USER, "registered")))
您可以使用JsonUnit它具有您正在寻找的function,我们可以忽略空的字段,路径和值等。请查看更多信息。 至于示例,您可以忽略这样的路径
assertJsonEquals( "{\"root\":{\"test\":1, \"ignored\": 2}}", "{\"root\":{\"test\":1, \"ignored\": 1}}", whenIgnoringPaths("root.ignored") );
有时您需要在比较时忽略某些值。 可以像这样使用$ {json-unit.ignore}占位符
assertJsonEquals("{\"test\":\"${json-unit.ignore}\"}", "{\n\"test\": {\"object\" : {\"another\" : 1}}}");