如何在测试中检查自定义Django模型示例是否相等?

htrmnn0y  于 2022-12-05  发布在  Go
关注(0)|答案(2)|浏览(122)

我有一个脚本,它使用原始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)

我找不到这种Assert方法,但也许我遗漏了什么。是否有这样的方法,我遗漏了什么,或者这真的是检查字段相等性的最好方法吗?

z9smfwbn

z9smfwbn1#

我建议使用_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)
64jmpszr

64jmpszr2#

我同意@schillingt的回答,你应该在__dict__上使用_ meta.get_fields()。_meta.get_fields()提供了从Django模型的Angular 来看 * 有意义 * 的字段,而不仅仅是通过Python __dict__属性实现的所有字段。
但是,我建议定义一个“提取器”来返回您在比较中关心的结构位,而不是创建一些 * 伪 * Assert。* 伪 * Assert在可读性方面有点麻烦,我尽量避免使用它们。
下面是一个示例:

def extract_structural_values(model_instance, ignore_pk='id'):
    field_values = {}
    for field in model_instance._meta.get_fields():
        if field.name == ignore_pk:
            continue

        field_values[field.name] = getattr(model_instance, field.name)
    return field_values

在测试中,我可能会这样使用它:

# ...in some test class/function
self.assertEqual(
    extract_structural_values(actual_instance),
    extract_structural_values(expected_instance))
# or even
self.assertEqual(
    extract_structural_values(actual_instance),
    extract_structural_values(SomeModel(
        some_first_field='some value',
        some_second_field='some other value',
    )),
)

相关问题