【问题标题】:How to check custom Django model instance equality in tests?如何在测试中检查自定义 Django 模型实例是否相等?
【发布时间】:2019-01-17 21:40:48
【问题描述】:

我有一个脚本,它使用原始 SQL 将数百万条记录从遗留数据库导入 Django 数据库以提高效率。旧数据库没有 ID 主键,因此这些主键是在插入行时从序列中创建的。

我正在通过在遗留数据库中创建行、运行导入并验证我是否获得了正确的 Django 对象来测试此导入过程是否正常工作。测试的最后一部分通常看起来像这样:

actual = MyModel.objects.get(code=legacy_object_code)
expected = MyModel(
    id=actual.id,
    code=legacy_object_code,
    other_property=other_value,
    …
)

我必须从实际对象中提取 ID,否则无法测试这两个对象是否相等。但问题是self.assertEqual(expected, actual) 总是成功!这是因为Django object equality被定义为具有相同的类型和ID/PK。

我实际检查模型实例属性的解决方法是:

def assert_model_instance_field_equality(self, expected, actual):
    expected_dict = expected.__dict__
    expected_dict.pop('_state')
    actual_dict = actual.__dict__
    actual_dict.pop('_state')
    self.assertDictEqual(expected_dict, actual_dict)

我找不到这种assertion method,但也许我错过了一些东西。有没有这样的方法,我是否遗漏了什么,或者这真的是检查字段相等性的最佳方法吗?

【问题讨论】:

    标签: django


    【解决方案1】:

    我建议使用_meta.fields 属性而不是__dict__

    def assert_model_instance_fields_equal(self, model, expected, actual):
        for field_name in model._meta.get_fields()
            expected_value = getattr(expected, field_name)
            actual_value = getattr(actual, field_name)
            self.assertEqual(expected_value, actual_value)
    

    【讨论】:

    • 谢谢,这是一个有用的属性!我仍然会从所有字段中创建一个 dict,这样我就可以运行一个 assertDictEqual 并查看完整的对象差异。
    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 2019-09-01
    • 2015-08-11
    • 2013-07-15
    • 2021-09-28
    • 2012-03-17
    • 2016-03-13
    • 2011-05-04
    相关资源
    最近更新 更多