unit testing an update CBV

I’m writing tests for my app and I don’t have much experience with this. I’m trying to wrap my head around what I should be testing in an update view:

class CourseUpdateView(PermissionRequiredMixin, UpdateView):
    """ Edit the name of the classroom"""
    raise_exceptions = True
    permission_required = 'gradebook.change_course'
    permission_denied_message = "You don't have access to this."

    model = Course
    fields = ['course_name', 'grade_level', ]
    template_name_suffix = '_update'

    def get_success_url(self, *args, **kwargs):
        return reverse('gradebook:coursedetail', kwargs={'course_pk': self.object.pk})

Model

class Course(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    course_name = models.CharField(max_length=30)
    ELEM = 'ELEM'
    SEC = 'SEC'
    GRADELEVEL = [
        (ELEM, 'Grade 8-9'),
        (SEC, 'Grade 10-12'),
    ]
    grade_level = models.CharField(
        max_length=4, choices=GRADELEVEL, default=SEC)

    class Meta:
        constraints = [models.UniqueConstraint(
            fields=['user', 'course_name'], name="unique-user-course")]

    def __str__(self):
        return self.course_name

My searches on testing update views mostly show people testing a form, but I’m not using a form for this view. Should I be looking at the django code to see what methods the UpdateView uses and write tests for those (I did this, it through all the subclasses and mixins there are post, get, form_valid, get_form_kwargs and a few others)? Would I test the get_success_url? I guess this is a redirect test? I don’t know how I would test the kwargs. Same goes for testing the permission_required.

I thought I’d try to test form_valid but I don’t know the name of the form…

class CourseUpdateTests(TestCase):
    def setUp(self):
        self.user = CustomUser.objects.create_user(
            username='tester',
            email='tester@email.com',
            password='tester123',
            is_teacher=True,
            is_active=True,
        )
        self.user.save()

    def test_CourseUpdate_valid(self):
        # course_form is not the name of the form...
        form = course_form(data={
            'user' = self.user,
            'id' = 4d192045-07fa-477f-bac2-5a99fe2e7c04
            'course_name': "Science",
            'grade_level': "SEC"},
        )
        self.assertTrue(form.is_valid())

I would appreciate any advice on getting started with this.

I would test the following (my opinion alone):

  • Permission denied case
  • Invalid form submission
  • Successful form submission

You can use the RequestFactory class. Remember to call the setup function. This would allow you to unit test parts of the view best.

The other option is to use the test client and do more of an integration test.

UpdateView does behind the scenes. Use a browser’s developer tools to inspect the html of the view.

You can inspect the rendered HTML or use Django Debug Toolbar to inspect the template that’s used. The fields on the form should map to the fields that you’re defining on the view, fields = ['course_name', 'grade_level', ]