编写Django模型单元测试时,如何规避重复使用assertEqual?
优化Django单元测试中重复
assertEqual的方案 针对你遇到的重复使用assertEqual违反DRY原则的问题,这里有几个实用的优化方案:
方案一:循环遍历预期字段字典
把测试用的预期数据存在setUp阶段的字典里,然后在测试方法中循环遍历字典的键值对,一次性完成所有字段的校验:
class ContactTestCase(TestCase): def setUp(self): """Create model objects.""" self.expected_data = { 'name': 'Jane Doe', 'email': 'janedoe@gmail.com', 'phone': '+2348123940567', 'subject': 'Sample Subject', 'message': 'This is my test message for Contact object.' } Contact.objects.create(**self.expected_data) def test_user_can_compose_message(self): """ Test whether a user can compose a message in the contact form.""" test_contact = Contact.objects.get(name=self.expected_data['name']) for field, expected_value in self.expected_data.items(): self.assertEqual(getattr(test_contact, field), expected_value, msg=f"Field '{field}' does not match expected value")
这种方式不管后续新增多少字段,只需要在expected_data字典里添加对应的键值对即可,完全避免重复代码。
方案二:自定义通用断言方法
如果多个测试用例都需要类似的字段校验,可以在测试基类里封装一个通用断言方法,后续测试类继承该基类即可复用逻辑:
class BaseModelTestCase(TestCase): def assertModelFieldsEqual(self, instance, expected_data): """断言模型实例的指定字段与预期数据匹配""" for field, expected_value in expected_data.items(): self.assertEqual(getattr(instance, field), expected_value, msg=f"Mismatch in field '{field}'") class ContactTestCase(BaseModelTestCase): def setUp(self): """Create model objects.""" self.expected_data = { 'name': 'Jane Doe', 'email': 'janedoe@gmail.com', 'phone': '+2348123940567', 'subject': 'Sample Subject', 'message': 'This is my test message for Contact object.' } Contact.objects.create(**self.expected_data) def test_user_can_compose_message(self): """ Test whether a user can compose a message in the contact form.""" test_contact = Contact.objects.get(name=self.expected_data['name']) self.assertModelFieldsEqual(test_contact, self.expected_data)
方案三:用assertJSONEqual对比序列化数据
如果需要校验的字段较多,也可以把模型实例的目标字段序列化为字典,再用Django内置的assertJSONEqual直接对比整体结构(注意排除id、created_at这类自动生成的无关字段):
class ContactTestCase(TestCase): def setUp(self): """Create model objects.""" self.expected_data = { 'name': 'Jane Doe', 'email': 'janedoe@gmail.com', 'phone': '+2348123940567', 'subject': 'Sample Subject', 'message': 'This is my test message for Contact object.' } self.contact = Contact.objects.create(**self.expected_data) def test_user_can_compose_message(self): """ Test whether a user can compose a message in the contact form.""" # 提取需要校验的字段,排除自动生成字段 contact_data = {k: getattr(self.contact, k) for k in self.expected_data.keys()} self.assertJSONEqual(str(contact_data), str(self.expected_data))
内容的提问来源于stack exchange,提问作者Uchenna Adubasim
相关产品推荐
相关产品推荐

