How create model only for test.

I want to create Model in unitest only for test. e.g. in file tests/test_helpers.py

import unittest
from unittest.mock import patch, Mock, MagicMock
from django.db import models

class YearNum(models.Model):
    num = models.CharField(max_length=30)

    class Meta:
        managed = False
        ordering = ['num']

    def __str__(self):
        return self.num

class TestExtraAttribute(unittest.TestCase):
pass # the test continues

but I got

RuntimeError: Model class strategic-cli.tests.test_helpers.YearNum doesn’t declare an explicit app_label and isn’t in an application in INSTALLED_APPS.

What I want to achieve is to create a simple model YearNum for unitest and to test for this purpose.
I thought it would help to create a DiscoverRunner I went according to the instructions (specifically this runner), however, it didn’t help and still leaves RuntimeError even though I loaded all the models on m._meta.managed = True.
Can anyone help me how to create a model just for testing purposes and not get the code unnecessary in the django application? Thanks

1 Like

Hi @marosko89 — Good question.

There’s a (long-standing) open ticket for that as it happens:

https://code.djangoproject.com/ticket/7835

The solution I use is @charettes’ suggestion in comment:46 there. This works well, so :+1:

@adamchainz brought up similar, with reference to documenting the internal @isolate_apps decorator (ticket) (linked example usage)

Either of those should get you going. Would be interested to see what you settle on.

HTH.
Carlton

1 Like

Thanks for the ping @carltongibson

My only addition to what has already been said here is that the setup_test_app approach allows for the models to be picked up during test discovery and thus have their respective tables created while isolate_apps is more suited for interactions with models that don’t need to be backed by a table.

2 Likes

@marosko89 A bit late perhaps, but, here’s a related discussion: How to create a model dynamically just for testing

By the way: Using unittest.TestCase instead of django.test.TestCase can lead to unexpected issues, as described e.g. here.

Another solution is to create a test_app in your project and add required models to it (I usually put it inside core/tests).

Then add it to settings.test like:

INSTALLED_APPS += ['core.tests.test_app']

then:

python manage.py makemigrations test_app --settings=settings.test

and finally:

python manage.py test --settings=settings.test

1 Like