【问题标题】:Django - How to write unit test checking if ValidationError was raised by ModelForm clean() for ManyToMany relationship?Django - 如何编写单元测试检查 ValidationError 是否由 ModelForm clean() 引发多对多关系?
【发布时间】:2019-07-12 12:38:50
【问题描述】:

我的模型中有 ManyToMany 字段,并且我在仅为此目的创建的 ModelForm 表单中为其编写了自定义验证。验证工作正常,但我不知道如何正确编写单元测试。

#models.py

class Course(models.Model):
    # some code
    max_number_of_students = models.PositiveSmallIntegerField(
        default=30)

class ClassOccurrence(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)    
    students = models.ManyToManyField(User, blank=True)
    # some code
# forms.py

class ClassOccurrenceForm(forms.ModelForm):
    # some code

    def clean(self):
        # Checks if number of students inscribed is not greater than allowed
        # for the course
        cleaned_data = super(ClassOccurrenceForm, self).clean()
        students = cleaned_data.get('students')
        course = cleaned_data.get('course')
        if students and course:
            if students.count() > course.max_number_of_students:
                raise ValidationError({
                    'students': "Too many students!})
        return cleaned_data

问题出在这部分:

# tests.py

    # some code
    def test_clean_number_of_students_smaller_than_max_students_number(self):        
        self.course_0.max_number_of_students = 5
        self.course_0.save()
        users = UserFactory.create_batch(10)
        self.assertRaises(ValidationError, self.class_occurrence_0.students.add(*users))      
        try:
            self.class_occurrence_0.students.add(*users)                
        except ValidationError as e:
            self.assertEqual(e.errors, {'students': ["Too many students!"]})

目前它不能按预期工作。似乎在测试方法中 ValidationError 没有在应该引发的地方引发。有人可以帮我解决吗?

【问题讨论】:

  • 我不明白你为什么认为这里会出现错误。首先,表单在内部捕获 ValidationErrors 并使用它们来填充表单错误。但其次,您甚至没有在测试中使用该表单
  • @DanielRoseman 感谢您的提示!我是 Django 初学者。现在我使用表格,它似乎没问题。然而,我不得不在参数中定义“课程”,这对我来说很奇怪,因为它已经被指定,例如 form = ClassOccurrenceForm({'students':[*users], 'course': self.course_0.pk}, instance=self.class_occurrence_0) 有没有办法避免它?

标签: python django unit-testing


【解决方案1】:

所以这似乎有效:

    #tests.py
    def test_clean_number_of_students_smaller_than_max_students_number(self):
        '''Check if number of students is not bigger than maximum number'''
        self.course_0.max_number_of_students = 5
        self.course_0.save()
        users = UserFactory.create_batch(10)
        form = ClassOccurrenceForm(
            {'students':[*users], 'course': self.course_0.pk}, 
            instance=self.class_occurrence_0
        )
        self.assertEqual(form.errors, 
            {'students': ["Too many students!"]})

【讨论】:

    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多