Skip to content

Instantly share code, notes, and snippets.

@a3dho3yn
Last active March 26, 2024 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a3dho3yn/82d400fd46f338821516ab3c6f72a843 to your computer and use it in GitHub Desktop.
Save a3dho3yn/82d400fd46f338821516ab3c6f72a843 to your computer and use it in GitHub Desktop.
Utility class to test Django abstract/mixin models
from django.db import connection
from django.db.models.base import ModelBase
from django.test import TestCase
class AbstractModelTestCase(TestCase):
"""Utility class to test abstract/mixin models
Abstract models doesn't allow you to make instances and Django will not create tables for them.
This utility class creates a temporary subclass for the abstract models, and creates the table for it.
How to use?
- Your test case should inherit this class (instead of Django TestCase)
- Set `mixin = YourAbstractModelClass` in your class
- Optionally, you can type hint `model: YourAbstractClass`
- Use self.model in your tests as the class under the test (e.g. self.model() creates a new record)
"""
mixin = None # Abstract [mixin] model class
model = None # Temporary subclass of the abstract model
@classmethod
def setUpClass(cls) -> None:
class Meta:
"""Meta options for the temporary model
app_label is required because this temporary model is not defined under a registered app
"""
app_label = cls.mixin.__module__
cls.model = ModelBase(
"TestModel" + cls.mixin.__name__,
(cls.mixin,),
{
"__module__": cls.mixin.__module__,
"Meta": Meta
}
)
with connection.schema_editor() as editor:
editor.create_model(cls.model)
super().setUpClass()
@classmethod
def tearDownClass(cls) -> None:
super().tearDownClass()
with connection.schema_editor() as editor:
editor.delete_model(cls.model)
connection.close()
from .abstract_model_test_case import AbstractModelTestCase
class TestSomeAbstractModel(AbstractModelTestCase):
mixin = SomeAbstractModel
model: SomeAbstractModel
def setUp(self) -> None:
super().setUp()
self.record = self.model()
self.record.save()
def test_created():
self.assertEqualt(1, self.model.objects.count())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment