如何编写单元测试以检查Django模型形式是否有效? [英] How can I write a unittest to check that a django model form is valid?

查看:94
本文介绍了如何编写单元测试以检查Django模型形式是否有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试模型表单是否有效。

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()

The query would return results if you pressed the "Save" button or if you do a form.save().

这篇关于如何编写单元测试以检查Django模型形式是否有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆