【问题标题】:Django Channels HttpClient testing errorDjango Channels HttpClient 测试错误
【发布时间】:2016-10-19 04:43:41
【问题描述】:

我一直在尝试为频道的多聊天示例项目中的一位消费者创建测试:https://github.com/andrewgodwin/channels-examples/tree/master/multichat。消费者函数如下所示:

@channel_session_user
def chat_join(message):
    print(message.content)
    room = get_room_or_error(message[MsgFields.ROOM], message.user)

    if NOTIFY_USERS_ON_ENTER_OR_LEAVE_ROOMS:
        room.send_msg(None, message.user.nickname, message.user.id, MSG_TYPE_ENTER)

    room.websocket_group.add(message.reply_channel)
    message.channel_session[ChannelSession.ROOMS] = list(set(message.channel_session[ChannelSession.ROOMS]).union([room.id]))

    recent_msgs = Message.objects.filter(room=room.id).order_by(ChatModelFields.CREATED_AT)[:10]
    history = []
    for msg in recent_msgs:
        history.append({
            ChatModelFields.CONTENT: msg.content,
            ChatModelFields.CREATOR: msg.creator,
            MsgFields.MSG_TYPE: MSG_TYPE_MESSAGE,
        })

    message.reply_channel.send({
        'text': json.dumps({
            MsgFields.USER_JOIN: str(room.id),
            'history': history,
        })
    })

现在,我一直遇到的有趣错误是这样的。 在我的测试功能版本 1 中:

 def test_chat_send(self):
        user = HubUser.objects.create_user(
            self.TEST_EMAIL,
            password=self.TEST_PASSWORD,
            nickname=self.TEST_NICKNAME
        )
        room = ChatRoom.objects.create(creator=self.TEST_NICKNAME)

        msg_join = {
            MsgFields.ROOM: 1,
            MsgFields.COMMAND: 'join',
        }
        msg_send = {
            MsgFields.MESSAGE: self.TEST_MSG,
            MsgFields.CREATOR: user,
            MsgFields.ROOM: 1,
            MsgFields.COMMAND: 'send',
        }

        c = HttpClient()
        c.login(username=self.TEST_EMAIL, password=self.TEST_PASSWORD)
        c.send_and_consume(RECEIVER_CHANNEL, content=msg_join, fail_on_none=True)

测试给了我以下错误:

Traceback (most recent call last):
  File "J:\Web\HubService\src\chat\tests\tests.py", line 60, in test_chat_send
    c.send_and_consume(RECEIVER_CHANNEL, content=msg_join, fail_on_none=True)
  File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\tests\base.py", line 127, in send_and_consume
    return self.consume(channel, fail_on_none=fail_on_none)
  File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\tests\base.py", line 118, in consume
    raise AssertionError("Can't find consumer for message %s" % message)
AssertionError: Can't find consumer for message <channels.message.Message object at 0x0000000006086B70>

测试功能版本2:

def test_chat_send(self):
            user = HubUser.objects.create_user(
                self.TEST_EMAIL,
                password=self.TEST_PASSWORD,
                nickname=self.TEST_NICKNAME
            )
            room = ChatRoom.objects.create(creator=self.TEST_NICKNAME)

            msg_join = {
                MsgFields.ROOM: 1,
                MsgFields.COMMAND: 'join',
            }
            msg_send = {
                MsgFields.MESSAGE: self.TEST_MSG,
                MsgFields.CREATOR: user,
                MsgFields.ROOM: 1,
                MsgFields.COMMAND: 'send',
            }

            c = HttpClient()
            c.login(username=self.TEST_EMAIL, password=self.TEST_PASSWORD)
            c.send(RECEIVER_CHANNEL, content=msg_join)
            c.consume(RECEIVER_CHANNEL, fail_on_none=True)

测试现在可以成功地将消息路由到正确的消费者,但由于用户身份验证而无法继续:

Traceback (most recent call last):
  File "J:\Web\HubService\src\chat\tests\tests.py", line 59, in test_chat_send
    c.consume(RECEIVER_CHANNEL, fail_on_none=True)
  File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\tests\base.py", line 116, in consume
    return consumer(message, **kwargs)
  File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\sessions.py", line 64, in inner
    return func(message, *args, **kwargs)
  File "C:\Users\Doge\Envs\dogeenv\lib\site-packages\channels\auth.py", line 42, in inner
    return func(message, *args, **kwargs)
  File "J:\Web\HubService\src\chat\consumers.py", line 38, in chat_join
    room = get_room_or_error(message[MsgFields.ROOM], message.user)
  File "J:\Web\HubService\src\chat\utils.py", line 24, in get_room_or_error
    raise ClientError("User not logged in")
chat.exceptions.ClientError: User not logged in

我的问题是:

1) 为什么分别调用HttpClient.sendHttpClient.consume 会产生与调用HttpClient.send_and_consume 不同的行为。我查看了 send_and_consume 函数,它只是像我做的那样分别调用发送和消费。

2) 我怎样才能让它工作,这样我就不会收到用户登录错误?

【问题讨论】:

    标签: django django-testing django-channels


    【解决方案1】:

    我实际上是在更多挖掘之后找到了答案。

    1) send_and_consume 的行为与调用 send 然后调用 consume 不同,因为我在这里使用的是 HttpClient。 HttpClient 继承自 Client 并拥有自己的 send 方法实现,但它没有实现 send_and_consume 方法。如果您调用 send_and_consume,您实际上是在调用 Client.sendClient.consume,但在我的情况下,我需要 HttpClient.sendClient.consume

    2) 为了避免用户登录错误,我必须初始化一个会话。这可以在另一个消费者内部完成。在示例中是这样的:

    @channel_session_user_from_http
    def ws_connect(message):
        # Initialise their session
        message.channel_session['rooms'] = []
    

    这是我将所有部分放在一起后的代码:

    def user_connect(self, client):
        client.send('websocket.connect', path='/chat/stream')
        client.consume('websocket.connect', fail_on_none=True)
    
    def test_chat_join(self):
        user = HubUser.objects.create_user(
            self.TEST_EMAIL,
            password=self.TEST_PASSWORD,
            nickname=self.TEST_NICKNAME
        )
        room = ChatRoom.objects.create(creator=self.TEST_NICKNAME)
    
        c = HttpClient()
        c.login(username=self.TEST_EMAIL, password=self.TEST_PASSWORD)
        self.user_connect(c)
        msg_join = {
            MsgFields.ROOM: 1,
            MsgFields.COMMAND: 'join',
        }
        c.send(RECEIVER_CHANNEL, content=msg_join)
        c.consume(RECEIVER_CHANNEL, fail_on_none=True)
        # asserts and etc...
    

    我希望这对遇到类似问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-08
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 2019-04-02
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多