Django ModelForm含ModelChoiceField的测试用例编写问询
编写Django AppleOrangeAssignmentForm的测试用例
没问题,针对你这个表单,我们可以从核心业务逻辑出发,覆盖几个关键测试场景,确保表单行为完全符合预期。下面是具体的测试思路和代码示例:
测试核心场景
我们需要重点验证这几个关键点:
- 表单初始化时,下拉选项仅展示未分配给任何Apple的Orange实例
- 提交有效数据后,Orange能正确关联到目标Apple
- 必填字段验证正常(未选择Orange时表单报错)
- 尝试手动提交已分配的Orange ID时,表单能识别并拒绝
完整测试代码示例
from django.test import TestCase from .models import Apple, Orange from .forms import AppleOrangeAssignmentForm class AppleOrangeAssignmentFormTest(TestCase): def setUp(self): # 提前准备测试数据:已分配/未分配的Orange,以及测试用Apple self.unassigned_orange1 = Orange.objects.create(name="未分配橙子1") self.unassigned_orange2 = Orange.objects.create(name="未分配橙子2") self.assigned_apple = Apple.objects.create(name="已关联苹果") self.assigned_orange = Orange.objects.create(name="已分配橙子", apple=self.assigned_apple) self.test_apple = Apple.objects.create(name="待分配苹果") def test_form_queryset_only_shows_unassigned_oranges(self): # 初始化表单 form = AppleOrangeAssignmentForm(instance=self.test_apple) # 提取下拉选项里的所有Orange ID form_orange_ids = [choice[0] for choice in form.fields['orange'].queryset.values_list('id', flat=True)] # 验证未分配的Orange在选项中,已分配的不在 self.assertIn(self.unassigned_orange1.id, form_orange_ids) self.assertIn(self.unassigned_orange2.id, form_orange_ids) self.assertNotIn(self.assigned_orange.id, form_orange_ids) def test_form_valid_submission_assigns_orange_to_apple(self): # 构造有效表单数据 form_data = {'orange': self.unassigned_orange1.id} form = AppleOrangeAssignmentForm(instance=self.test_apple, data=form_data) # 验证表单有效并保存 self.assertTrue(form.is_valid()) form.save() # 刷新数据库实例,确认关联关系生效 self.test_apple.refresh_from_db() self.assertEqual(self.test_apple.orange, self.unassigned_orange1) # 额外验证:该Orange现在已被分配,不会出现在后续表单的选项中 new_form = AppleOrangeAssignmentForm(instance=self.test_apple) new_form_orange_ids = [choice[0] for choice in new_form.fields['orange'].queryset.values_list('id', flat=True)] self.assertNotIn(self.unassigned_orange1.id, new_form_orange_ids) def test_form_invalid_when_no_orange_selected(self): # 提交空的orange字段 form_data = {'orange': ''} form = AppleOrangeAssignmentForm(instance=self.test_apple, data=form_data) # 验证表单无效,且有对应的必填错误提示 self.assertFalse(form.is_valid()) self.assertIn('orange', form.errors) self.assertEqual(form.errors['orange'][0], 'This field is required.') def test_form_invalid_when_assigning_already_assigned_orange(self): # 手动构造已分配Orange的ID提交(模拟前端绕过下拉的恶意场景) form_data = {'orange': self.assigned_orange.id} form = AppleOrangeAssignmentForm(instance=self.test_apple, data=form_data) # 验证表单无效,因为该Orange不在合法的queryset范围内 self.assertFalse(form.is_valid()) self.assertIn('orange', form.errors)
代码说明
setUp方法:提前创建所有测试需要的实例,避免每个测试重复造数据,提升测试效率test_form_queryset_only_shows_unassigned_oranges:直接检查表单的queryset内容,确保你的过滤逻辑生效test_form_valid_submission_assigns_orange_to_apple:端到端验证完整提交流程,包括关联后的状态变化test_form_invalid_when_no_orange_selected:验证必填字段的基础校验逻辑test_form_invalid_when_assigning_already_assigned_orange:额外测试后端防护,防止恶意提交已分配的Orange
这样写的测试用例就能全面覆盖你表单的核心逻辑啦~
内容的提问来源于stack exchange,提问作者TAH
相关产品推荐
相关产品推荐

