Single Entity
Single Entity

Reputation: 3115

Django 3 test to catch ValidationError is not recognising the raised error

I'm struggling to get my Django test to succeed. The test file is as follows, I've kept it as simple as I can:

from django.test import TestCase
from django.core.exceptions import ValidationError

from .models import Reporter

class NewReporterTests(TestCase):
    def test_reporter_name_should_not_be_empty(self):
        """
        Checking new reporter name cannot be empty and raises validation error correctly
        """
        blank_reporter = Reporter(full_name="")
        self.assertRaises(ValidationError, blank_reporter.save())

The code which is firing the exception is in the data model as follows:

class Reporter(models.Model):
    uuid = models.UUIDField(default = uuid.uuid4, editable = False, unique=True)
    full_name = models.CharField(max_length=70)

    def save(self, *args, **kwargs):
        if self.full_name == '':
            raise ValidationError('full_name is empty and is not allowed to be')
        super(Reporter, self).save(*args, **kwargs)

    def __str__(self):
        return self.full_name

The output from python manage.py test is:

======================================================================
ERROR: test_reporter_name_should_not_be_empty (gallery.tests.NewReporterTests)
Checking new reporter name cannot be empty and raises validation error correctly
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/james/repos/django_play/gallery/tests.py", line 14, in test_reporter_name_should_not_be_empty
    self.assertRaises(ValidationError, blank_reporter.save())
  File "/home/james/repos/django_play/gallery/models.py", line 17, in save
    raise ValidationError('full_name is empty and is not allowed to be')
django.core.exceptions.ValidationError: ['full_name is empty and is not allowed to be']

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)
Destroying test database for alias 'default'...

So the test is creating a new reporter with a blank user name which should raise an exception in the save method of the model. This does happen, but the test still fails even though (as far as I understand it) assertRaises should succeed, so I'm concerned I am misunderstanding something fundamental.

Upvotes: 4

Views: 1454

Answers (1)

JPG
JPG

Reputation: 88429

The second parameter of assertRaises(...) should be callable hence you should use blank_reporter.save instead of blank_reporter.save()

class NewReporterTests(TestCase):
    def test_reporter_name_should_not_be_empty(self):
        blank_reporter = Reporter(full_name="")
        self.assertRaises(ValidationError, blank_reporter.save)

Alternatively, You can use with syntax

class NewReporterTests(TestCase):
    def test_reporter_name_should_not_be_empty(self):
        blank_reporter = Reporter(full_name="")
        with self.assertRaises(ValidationError) as ctx:
            blank_reporter.save()

You can also use the assertRaisesMessage(...) instead of assertRaises(...) as

class NewReporterTests(TestCase):
    def test_reporter_name_should_not_be_empty(self):
        blank_reporter = Reporter(full_name="")
        with self.assertRaisesMessage(
                ValidationError,
                'full_name is empty and is not allowed to be'
        ):
            blank_reporter.save()

Upvotes: 5

Related Questions