Django: How to create a model dynamically just for testing


@paluh's answer requires adding unwanted code to a non-test file and in my experience, @carl's solution does not work with django.test.TestCase which is needed to use fixtures. If you want to use django.test.TestCase, you need to make sure you call syncdb before the fixtures get loaded. This requires overriding the _pre_setup method (putting the code in the setUp method is not sufficient). I use my own version of TestCase that let's me add apps with test models. It is defined as follows:

from django.conf import settings
from import call_command
from django.db.models import loading
from django import test

class TestCase(test.TestCase):
    apps = ()

    def _pre_setup(self):
        # Add the models to the db.
        self._original_installed_apps = list(settings.INSTALLED_APPS)
        for app in self.apps:
        loading.cache.loaded = False
        call_command('syncdb', interactive=False, verbosity=0)
        # Call the original method that does the fixtures etc.
        super(TestCase, self)._pre_setup()

    def _post_teardown(self):
        # Call the original method.
        super(TestCase, self)._post_teardown()
        # Restore the settings.
        settings.INSTALLED_APPS = self._original_installed_apps
        loading.cache.loaded = False

I have a Django app that requires a settings attribute in the form of:

RELATED_MODELS = ('appname1.modelname1.attribute1',
                  'appname2.modelname3.attribute3', ...)

Then hooks their post_save signal to update some other fixed model depending on the attributeN defined.

I would like to test this behaviour and tests should work even if this app is the only one in the project (except for its own dependencies, no other wrapper app need to be installed). How can I create and attach/register/activate mock models just for the test database? (or is it possible at all?)

Solutions that allow me to use test fixtures would be great.

Test specific models in Django

You could try creating a whole new app that you only use on your development server.

E.g., if your app is called myapp you would call your testing app myapp_test.

Then in myapp_test's you would from myapp import models and then subclass your models in there.

Then in your you either just try and remember to comment out the myapp_test application from INSTALLED_APPS when deploying to your production server. Or you can use the methodology to only have the myapp_test included in INSTALLED_APPS on your test machine.

You should use a local import within a package:

from .test_model import *