Тестовая база данных не хранит данные во время теста Pytest Django Channels - PullRequest
1 голос
/ 16 мая 2019

Я пишу тесты для приложения Django Channels, следуя документации . Я могу успешно проверить соединение и связь с потребителем WebSocket. Однако в одном из тестов мне нужно создать пользователя.

Это мой метод испытаний:

@pytest.mark.django_db
@pytest.mark.asyncio
async def test_1():
    my_user = get_user_model().objects.create_user(username='my_user', email='user@user.com', password='123456')
    my_user.save()

    print(User.objects.all())

    communicator = WebsocketCommunicator(MyConsumer, '/websocket/')
    communicator.instance.scope['user'] = my_user
    connected, subprotocol = await communicator.connect()
    assert connected
    await communicator.send_json_to({
        'command': 'test',
    })
    response = await communicator.receive_json_from(timeout=5)
    await communicator.disconnect()

Ошибка возникает в методе, который обрабатывает случай 'command' == 'test'. Когда он пытается сохранить другой экземпляр модели, в котором в качестве внешнего ключа указан пользователь, проверка завершается неудачей.

client = Client(user=scope['user'])
client.save()

Если я добавлю print(User.objects.all()) к методу внутри потребителя (между двумя предыдущими строками), он вернет пустой QuerySet, а первый print в самом методе теста вернет созданного пользователя. Конечно, поскольку пользователя нет, тест не пройден с:

django.db.utils.IntegrityError: insert or update on table "chat_client" violates foreign key constraint "chat_client_user_id_d10928fc_fk_auth_user_id"
DETAIL:  Key (user_id)=(1) is not present in table "auth_user".

Я попытался превратить создание пользователя в другой асинхронный метод и await для него, но ничего не изменилось. Почему таблица User очищается во время выполнения теста? Как сохранить данные, созданные в начале теста?

1 Ответ

1 голос
/ 20 мая 2019

Как указано @hoefling в комментариях, единственное, чего не хватало, это сделать тест транзакционным, как видно из этого вопроса .

В моем случае мне нужно было только изменить тестовый декоратор на:

@pytest.mark.django_db(transaction=True)
...