如何编写单元测试以检查Django模型形式是否有效? [英] How can I write a unittest to check that a django model form is valid?
问题描述
我正在尝试测试模型表单是否有效。
I am trying to test that a model form is valid.
在测试功能中,我创建了两个自定义表单模型。我添加数据以填写表单的必填字段。
In the test function, I create the two models that feature in my custom form. I add the data to fill the form's required fields.
当我运行测试并在表单上调用 is_valid()
时,测试失败,并且表单给出了错误,我添加的选项是不是可用选项之一
。这向我表明我已将 Option
实例错误地添加到表单或测试中。我不确定如何使用。
When I run the tests and call is_valid()
on the form, the test fails and the form gives the error that the option that I have added is not one of the available choices
. This suggests to me that I have incorrectly added the Option
instance to the form or to the test. I am unsure how.
如何使模型形式对测试有效?
How can I make the model form valid for the test?
tests.py
def test_valid_data(self):
question_1 = Question(
question_text='What is the width of the telephone?',
date_published=timezone.now(),
collection=Collection.objects.create()
)
question_1.save()
option_1 = question_1.options.create(
question=question_1,
option_text='Five centimetres'
)
option_1.save()
data = {'question_text': question_1.question_text, 'selected_option': option_1.option_text,}
form = QuestionForm(data=data)
print(form)
self.assertTrue(form.is_valid())
forms.py
class QuestionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(QuestionForm, self).__init__(*args, **kwargs)
self.fields['selected_option'] = forms.ChoiceField(
choices=[
(f'{option.pk}', f'{option}')
for option in Option.objects.filter(question_id=self.instance.pk)
],
widget=RadioSelect,
required=True,
error_messages={
'required': 'The question form lacks a selected_option'
}
)
class Meta:
model = Question
fields = ('question_text',)
labels = {
'question_text': ''
}
widgets = {
'question_text': forms.Textarea(attrs={'cols': '40', 'rows': '2'})
}
models.py
class Question(models.Model):
question_text = models.CharField(max_length=400)
collection = models.ForeignKey(Collection, on_delete=models.PROTECT, default=None)
date_published = models.DateTimeField('date published')
def __str__(self) -> str:
return self.question_text
class Option(models.Model):
option_text = models.CharField(max_length=400)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
class Meta:
default_related_name = 'options'
def __str__(self) -> str:
return self.option_text
预期: is_valid()
-> True
实际值: is_valid()
-> 错误
推荐答案
问题是由您在 QuestionForm .__ init __
中定义选项的方式引起:
The issue is caused by the way that you have defined choices in QuestionForm.__init__
:
choices=[
(f'{option.pk}', f'{option}')
for option in Option.objects.filter(question_id=self.instance.pk)
],
您已根据以下内容创建了个选择
与 QuestionForm
相关的 Question
实例的 pk
发起。
You have created choices
based on the pk
of the Question
instance related with the QuestionForm
you initiate.
在您的测试中(以及在管理员中),表单
不受任何<$通过输入
form = QuestionForm(data = data)
初始化表单时,出现c $ c>问题。
In your test (and also in the admin), the form
is not bound to any instance of Question
when you initiate the form by entering
form = QuestionForm(data=data)
.
因此,查询 Option.objects.filter(question_id = self.instance.pk)
返回 None
,因为 self.instance.pk
是 None
。
Consequently, the query Option.objects.filter(question_id=self.instance.pk)
returns None
because self.instance.pk
is None
.
因此,在保存 QuestionForm
之前,您会收到错误消息,因为 choices = []
Therefore, you receive the error before saving the QuestionForm
because choices = []
如果您按下保存按钮或执行 form.save()$ c,查询将返回结果$ c>。
The query would return results if you pressed the "Save" button or if you do a form.save()
.
这篇关于如何编写单元测试以检查Django模型形式是否有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!