Есть ли правильный способ заставить мальчика-фабриканта подключиться к тестовой базе данных?

У меня возникает очень раздражающая ошибка в тестовых наборах моего проекта, потому что factory boy запускает каждый тестовый пример на основной/дефолтной базе данных, вместо того чтобы запускать запросы на соответствующей тестовой базе данных.

Я попробовал добавить конфигурацию класса Meta в фабричный класс (как рекомендовано в этом посте), но как только я пытаюсь запустить набор тестов django, приложение выдает ошибку, утверждая, что соединение с тестовой базой данных не существует.

Буду очень признателен за любую помощь, поскольку документация совершенно не проясняет эту ситуацию.

Мой settings.py:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": 'DB_NAME',
        "USER": 'DB_USER',
        "PASSWORD": 'DB_PSSWD',
        "HOST": 'DB_HOST',
        "PORT": 3306,
        "TEST":{
            "NAME": 'TEST_DB_NAME',
        },
        "OPTIONS": {
            "init_command": "SET sql_mode='STRICT_TRANS_TABLES'; SET foreign_key_checks = 0;",
        },
    }
}

my factory.py:

import factory

class CustomModelFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.CustomModel
        database = 'TEST_DB_NAME'
        django_get_or_create = ('nu_cnpj',)

    nm_razao_social = factory.Faker(locale='pt_BR', provider='company')
    nu_cnpj = factory.Faker(locale='pt_BR', provider='company_id')

my model.py:

from django.db import models

class CustomModel(models.Model):
    nu_cnpj = models.CharField(unique=True, max_length=20, blank=True, null=True)
    nm_razao_social = models.CharField(max_length=255, blank=False, null=False)

Ошибка:

python manage.py test flux.tests.test_data_leak_main_db --keepdb
Traceback (most recent call last):
  File "C:\Users\project\venv\lib\site-packages\django\db\utils.py", line 172, in ensure_defaults
    conn = self.databases[alias]
KeyError: 'TEST_DB_NAME'

During handling of the above exception, another exception occurred:
...
    raise ConnectionDoesNotExist("The connection %s doesn't exist" % alias)
django.db.utils.ConnectionDoesNotExist: The connection TEST_DB_NAME doesn't exist

В конце концов, я и мои коллеги по команде смогли отследить, какая именно реализация фабрики генерировала это странное поведение.Был вызов фабрики внутри определения класса фабрики, что привело к вставке данных во время фазы импорта (которая предшествовала созданию тестовой базы данных из базы данных по умолчанию). Поэтому объекты фабрик вставлялись в базу данных по умолчанию, которая была единственной доступной для ORM.

Ошибочная реализация выглядела следующим образом:

import factory

class CustomModelFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = models.CustomModel
        database = 'TEST_DB_NAME'
        django_get_or_create = ('nu_cnpj',)

    nm_razao_social = factory.Faker(locale='pt_BR', provider='company')
    nu_cnpj = factory.Faker(locale='pt_BR', provider='company_id')

    class Params:
        test = factory.Trait(
            nm_razao_social='Test',
        )

class ForeignRelatedCustomModelFactory(factory.django.DjangoModelFactory):

    name = factory.Faker(locale='pt_BR', provider='first_name')
    address = factory.Faker('address')
    status = factory.Faker('pystr')
    fk = factory.SubFactory('CustomModelFactory')

    class Params:
        test = factory.Trait(
            fk=CustomModelFactory(test=True), # this line resulted in a factory call during import, inserting data into the 'default' database instead of the test replica db, during the execution of `python manage.py test`
            name='Test'
        )
Вернуться на верх