对字符串化的JSON进行分类

时间:2016-10-28 17:53:03

标签: python json string unit-testing

我有一个看起来像

的功能
def function_to_test(data):
    data = some_operations_inline(data)
    return stringify_json(data)

,其中

def stringify_json(data):
    return json.dumps(data, encoding='utf-8')

我想进行单元测试function_to_testtox + nose)。问题是字符串中元素的排序随PYTHONHASHSEED而变化。

我尝试将功能更改为:

def stringify_json(data):
    sorted_dict = OrderedDict([[k, v] for k, v in sorted(data.items())])
    return json.dumps(sorted_dict, encoding='utf-8')

但如果data包含另一个dict,则无效。

我该如何测试?显而易见的是比较json值,而不是它们的字符串版本:

self.assertEqual(
    json.loads(expected),
    json.loads(computed)
)

这可以接受吗?即使我没有测试实际功能输出?我想我们可以假设json.dumps已经过测试。 注意:我封装了json.dumps,因此我可以确保所有转储都是一致的。

2 个答案:

答案 0 :(得分:1)

  

我该如何测试?显而易见的是比较json   值,而不是它们的字符串版本:

self.assertEqual(
    json.loads(expected),
    json.loads(computed)
)
     

这可以接受吗?即使我没有测试真正的功能   输出

正在测试实际功能输出。这不像你将假输出插入第二个json.loads调用。您确认输出具有所需的属性:具体而言,输出反序列化为正确的数据。

在这里使用json.loads是正确的做法。

答案 1 :(得分:0)

您可以编写自己的转储功能:

def sorted_json_dump(x):
    if isinstance(x, str):
        return '"{}"'.format(repr(x)[1:-1])
    elif isinstance(x, list):
        return "[{}]".format(", ".join(sorted_json_dump(i) for i in x))
    elif isinstance(x, dict):
        return "{{{}}}".format(", ".join(
            "{}: {}".format(
                repr(str(sorted_json_dump(k)))[1:-1],
                sorted_json_dump(v)
            )
            for k, v in sorted(x.items(), key = lambda i: i[0])
        ))
    else:
        return repr(x)