Django abstract model + DB migrations: tests throw "cannot ALTER TABLE because it has pending trigger events"
Common practice for testing abstract models is to create actual models just for tests
here is example in model-utils
project https://github.com/jazzband/django-model-utils/blob/master/tests/test_models/test_timestamped_model.py
from tests.models import UserableTestclass TestUserable(TestCase): def setUp(self): user = User.objects.create_user( email="testuser@test.com", name="Test User", password="test1234test" ) self.user = user def test_user(self): UserableTest.objects.create(user=self.user) self.assertEqual(UserableTest.objects.count(), 1)
In this project they have separate settings DJANGO_SETTINGS_MODULE = tests.settings
https://github.com/jazzband/django-model-utils/blob/master/tests/settings.py
INSTALLED_APPS = ( 'model_utils', 'tests',)DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3' }}SECRET_KEY = 'dummy'
And models are described in https://github.com/jazzband/django-model-utils/blob/master/tests/models.py
from myapp.models import Userableclass UserableTest(Userable): pass
Try below code. I've tested it it's working.
requirements.txt
Django==1.11.13pkg-resources==0.0.0pytz==2018.4
models.py
from django.conf import settingsfrom django.db import modelsclass Userable(models.Model): user = models.OneToOneField( settings.AUTH_USER_MODEL, on_delete=models.CASCADE ) class Meta: abstract = True
tests.py
# -*- coding: utf-8 -*-from __future__ import unicode_literalsfrom django.test import TestCasefrom .models import Userablefrom django.db import connectionfrom django.db.models.base import ModelBasefrom django.contrib.auth.models import Userclass TestUserable(TestCase): def setUp(self): user = User.objects.create_user( username="testuser@test.com", password="test1234test" ) self.user = user self.model = ModelBase( Userable.__name__, (Userable,), {'__module__': Userable.__module__} ) with connection.schema_editor() as schema_editor: schema_editor.create_model(self.model) def test_user(self): self.model.objects.create(user=self.user) self.assertEqual(self.model.objects.count(), 1) def tearDown(self): with connection.schema_editor() as schema_editor: schema_editor.delete_model(self.model)