如何在测试中检查自定义Django模型实例的相等性?

How to check custom Django model instance equality in tests?

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

我正在测试这个导入过程是否正常工作,方法是在旧数据库中创建行,运行导入并验证我是否能重新获得正确的django对象。测试的最后一部分通常看起来有点像这样:

1
2
3
4
5
6
7
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对象相等被定义为具有相同的类型和id/pk。

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

1
2
3
4
5
6
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)

我找不到这种断言方法,但可能我遗漏了一些东西。是否有这样的方法,我是否遗漏了一些东西,或者这真的是检查字段相等性的最佳方法?


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

1
2
3
4
5
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)