使用 ModelChoiceField 的 Django ModelForm 测试用例

TAH*_*TAH 0 django modelform django-testing

我正在尝试编写一个简单的测试用例来测试允许将Orange对象分配给Apple对象的 Django 表单。

表格.py

class AppleOrangeAssignmentForm(forms.ModelForm):
    orange = forms.ModelChoiceField(required=True, \ 
                 queryset=Orange.objects.filter(apple=None))

class Meta:
    model = Apple
    fields = ('orange')
Run Code Online (Sandbox Code Playgroud)

onquerysetorange为了确保下拉列表中的值只是Orange尚未分配给其他的Apple值。该代码在调用它的视图中正确且一致地工作。

在下面的测试用例中,我创建了一个全新的,Orange以确保我有一个它没有被分配到其他地方。

测试.py

def test_apple_orange_assignment(self):
    apple = Apple.objects.get(pk=1)
    self.assertEquals(apple.orange, None)

    orange = Orange.objects.create(name='clementime')
    form_data = { 'orange': orange }
    form = AppleOrangeAssignmentForm(data=form_data, instance=apple)
    self.assertTrue(form.is_valid()) # <=== Fails here
Run Code Online (Sandbox Code Playgroud)

奇怪的是,该表单在测试用例中没有验证! form.errors说:{'orange': ['Select a valid choice. That choice is not one of the available choices.']}。当我进一步挖掘时,我可以看到orange我试图分配的确实出现在 中form.fields['orange'].queryset

我已尽了一切努力来验证这一点。我尝试将queryset表单字段更改为Orange.objects.all()。我尝试更改orange测试用例中变量的创建form.fields['orange'].queryset[0],以确保我选择的是其选择中的橙色。但没有任何效果。

正如我所说,这一切在视图中都完美运行。我在测试用例中做错了什么?

sla*_*art 5

首先,不需要添加\after required=True \,因为语句将以括号结束。

实例化表单类时,您需要指定对象 ID,而不是整个橙色对象。

def test_apple_orange_assignment(self):
    # More code here
    form_data = { 'orange': orange.id }
    form = AppleOrangeAssignmentForm(data=form_data, instance=apple)
    assert form.is_valid(), form.errors
Run Code Online (Sandbox Code Playgroud)

就是这样!

提示:您可以使用assert False, form.as_p()使测试失败并跟踪表单 html,您会发现它不是在查找对象而是在查找 object_id。