I'm trying to test constraint validation in Django with a py.test
unit test by creating a child object for which the parent does not exist.
@pytest.mark.django_db
def test_child_with_missing_parent():
with pytest.raises(django.db.utils.IntegrityError):
Child.objects.create(parent_id=1337)
The exception is thrown, but can't be caught -- it just shows in stderr
. I'm using pytest.mark.xfail
for now, but it is effectively just a "skip" -- 1 xfailed, 1 xpassed
is the result. How could I catch such an error in an expected scenario like this?
Here is the exception / error which appears in the console but can't be caught:
self = <django.db.backends.utils.CursorWrapper object at 0x7fe1e2dea5f8>, sql = 'SET CONSTRAINTS ALL IMMEDIATE', params = None
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fe1ec724128>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7fe1e2dea5f8>})
def _execute(self, sql, params, *ignored_wrapper_args):
self.db.validate_no_broken_transaction()
with self.db.wrap_database_errors:
if params is None:
> return self.cursor.execute(sql)
E psycopg2.IntegrityError: insert or update on table "myapp_child" violates foreign key constraint "myapp_re_parent_id_537da634_fk_myapp_calc"
E DETAIL: Key (parent_id)=(1337) is not present in table "myapp_parent".
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:83: IntegrityError
The above exception was the direct cause of the following exception:
self = <django.test.testcases.TestCase testMethod=__init__>
Looks like you are trying to catch a different exception from what is raised. psycopg2.IntegrityError
is not the same as django.db.utils.IntegrityError
- and for some reason Django isn't wrapping this exception in its own wrapper.
This should work:
with pytest.raises(psycopg2.IntegrityError):
Child.objects.create(parent_id=1337)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With