Search code examples
python-asynciodjango-channelspytest-asyncio

How can I add the `url_route` key/value into the `scope` for tests?


I'm looking to test my consumer, which uses scope['url_route'] but using HttpCommunicator or ApplicationCommunicator, that param isn't set. How can I set this parameter? The testing documentation is very limited and doesn't have any documentation on this https://channels.readthedocs.io/en/latest/topics/testing.html.

test.py

from channels.testing import HttpCommunicator
import pytest

from my_app import consumers

@pytest.mark.asyncio
async def test_consumers():
    communicator = HttpCommunicator(consumers.MyConsumer, 'GET', '/project/1')
    response = await communicator.get_response()
    assert response['status'] == 400

my_app.py

import json

from channels.db import database_sync_to_async
from channels.generic.http import AsyncHttpConsumer

from projects import model

class MyConsumer(AsyncHttpConsumer):
    async def handle(self, body):
        _id = int(self.scope['url_route']['kwargs'].get('project_id', 1))
        record = await database_sync_to_async(models.Project.objects.get)(id=_id)
        data = json.dumps({"id": _id})
        await self.send_response(200, data.encode('utf8'))

Solution

  • Found the solution in the docs, but it was under the Websocket testing section, not in the HTTP section. Either import your asgi application or wrap the consumer in URLRouter then use that in HttpCommunicator. Turns out there's some flow that adds scope['url_route'] in URLRouter.