Reputation: 319
I'm writing tests for a Django Channels application following the documentation. I can successfully test connection and communication with the WebSocket consumer. However, in one of the tests I need to create a user.
This is my test method:
@pytest.mark.django_db
@pytest.mark.asyncio
async def test_1():
my_user = get_user_model().objects.create_user(username='my_user', email='[email protected]', 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()
The error occurs inside the method that handles the 'command' == 'test'
case. When it tries to save another model instance that has User as a foreign key, the test fails.
client = Client(user=scope['user'])
client.save()
If I add a print(User.objects.all())
to the method inside the consumer (between the previous two lines), it returns an empty QuerySet, while the first print
in the test method itself returns the created user. Of course, since there is no User, the test fails with:
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".
I tried turning user creation into another async method and await
ing for it, but nothing changed. Why is the User
table getting emptied during the test's execution? How can I keep data created at the beginning of the test?
Upvotes: 2
Views: 1325
Reputation: 319
As indicated by @hoefling in the comments, the only thing missing was to make the test transactional, as seen in this question.
In my case, I only had to change the test decorator to:
@pytest.mark.django_db(transaction=True)
Upvotes: 5