【问题标题】:Comparing two JSONObject structures (ignoring their values)?比较两个 JSONObject 结构(忽略它们的值)?
【发布时间】:2014-04-14 01:04:53
【问题描述】:

我正在寻找一个支持比较两个 JSON 对象的结构、忽略值​​trong>、子顺序以及(如果可能的话)可选地忽略响应中的其他元素的 JSON 配对库;专门用于针对预期结构对从 Web 服务返回的 JSON 进行单元测试。 (我想将一个示例响应传递给 assert 方法,并将其结构与实际响应进行比较 - 而不必为每个节点编写断言。只要结构良好,取回不同的值不是问题.)

任何主要的 JSON 库都支持这个吗? (这个问题与Compare two JSON objects in Java基本相同,但我希望断言忽略我的JSON结构中的值,这可能看起来像Wikipedia上的示例......)

【问题讨论】:

  • 定义你自己的比较器?
  • 请注意,鉴于键/值对是无序的,您需要定义两个 JSON 对象等价的含义。例如,你可以有{key1:string,key2:[array stuff]}{key3:[array stuff],key4:string}——它们是不是“相同的形状”?
  • 嗨@HotLicks,我会说它们不是,除非键相同 - 因为我不关心元素的顺序......所以,我期待匹配键 + 类型,但不匹配值...
  • 为此创建一个递归检查器是一项相对容易的工作。只需取一个值,对其执行instanceof 以查看它是哪种类型,路由到数组或映射子例程,让子例程遍历比较计数、键和类型的结构。如果在当前数组或映射例程中遇到数组或映射,则递归调用自己。当您得到不匹配时停止(并返回 false),当在给定级别没有更多可比较时返回 true。

标签: java json unit-testing


【解决方案1】:

您可能想看看 Guava 及其 Equivalence

例如,如果您使用 Jackson,您将编写一个 Equivalence<JsonNode>,您可以根据自己的需要进行自定义。

Here 是此类Equivalence 的一个示例,如果所有数字递归地在数学上相等,则它认为两个 JSON 值相等。

用法:yourEquivalence.equivalent(node1, node2)

另一种解决方案是编写一个 POJO,将其序列化为您想要的 JSON,并尝试将您的 JSON 反序列化为所述 POJO。如果反序列化失败,你的结构就是错误的。

【讨论】:

    【解决方案2】:

    我使用递归函数,如果你想忽略值类型,你可以通过返回 true 来改变最后一个 else 条件的内容。

    • dict_var 是你要验证的json
    • schema 是 dict_var 必须遵循的架构

    代码:

    def verify_config_parameters_structure(dict_var, schema):
    try:
        # If it's a dictionary
        if isinstance(dict_var, dict):
            if isinstance(schema, dict):
                # Verify The object does not have more keys
                for k2, v2 in dict_var.items():
                    if verify_config_parameters_structure(dict_var[k2], schema[k2]) is False:
                        return False
                # Verify The object does have at least the schema keys
                for k2, v2 in schema.items():
                    if verify_config_parameters_structure(dict_var[k2], schema[k2]) is False:
                        return False
                return True
            else:
                return False
        # If it's a list
        elif isinstance(dict_var, list):
            if isinstance(schema, list):
                for item in dict_var:
                    if verify_config_parameters_structure(item, schema[0]) is False:
                        return False
                return True
            else:
                return False
        # If it's a value
        else:
            if type(dict_var) is type(schema):
                return True
            else:
                return False
    except:
        return False
    

    【讨论】:

      猜你喜欢
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 2017-04-22
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多