测试Django频道消费者:“没有回复消息发送给消费者”

时间:2016-08-15 09:48:37

标签: django django-testing django-channels

我正在使用 Django频道@channel_session_user装饰器(用于访问Django的会话数据)。

@channel_session_user_from_http
def ws_connect(message):
    # creates group names like "group-1"
    group_kw = get_group_id_for_user(message.user)
    Group(group_kw).add(message.reply_channel)

@channel_session_user
def ws_receive(message):
    group_kw = get_group_id_for_user(message.user)
    payload = json.loads(message.content['text'])
    Channel(payload['action']).send(message.content)

@channel_session_user
def ws_disconnect(message):
    group_kw = get_group_id_for_user(message.user)
    Group(group_kw).discard(message.reply_channel)

工作正常,但测试时出现问题。

以下测试应在websocket.receive频道上发送消息,然后ws_receive应接收消息并将其置于消息action值中定义的频道上。最后,我测试它是否实际上放在那个频道上。

def test_send_chat_message_is_used_by_consumer(self):
    # Make sure a user is authenticated
    self.assertTrue(auth.get_user(self.client).is_authenticated())

    payload = {'action': 'chat.receive',
               'msg': 'Test message.',
               'receiver': self.user2.id}
    message = {'text': json.dumps(payload)}

    # Send a chat message
    Channel('websocket.receive').send(message)
    # Receive it and place it on the right channel
    ws_receive(self.get_next_message('websocket.receive', require=True))
    # Fetch it from the channel
    result = self.get_next_message(payload['action'], require=True)
    # That should be the message sent
    self.assertEqual(result, message)

相反,我收到以下错误,指向ws_receive()调用的行。

  

ValueError:没有向消费者发送reply_channel; @channel_session只能用于包含它的邮件。

频道来源中的错误is raised here

打印reply_channel返回None,而不是包含正确的回复频道名称。

tmp = self.get_next_message('websocket.receive', require=True)
print(tmp.reply_channel)  # prints: None

我忽略了一些明显的东西?

2 个答案:

答案 0 :(得分:1)

我认为你不能只是简单地调用消费者,因为它有装饰器@channel_session_user。您应该尝试使用客户端channels.tests提供。

from channels.tests import ChannelTestCase, Client

然后在测试函数中使用类似的东西

client = Client()
client.send('websocket.receive', content=message)

答案 1 :(得分:0)

这是因为您提供给'频道' object表示收到此消息的频道。查看频道的init function

还要注意tests / base.py文件中的函数get_next_message。此处的频道参数指的是在测试期间将消息发送到的(回复)频道。

回答您的问题 -

查看channels / message.py中的docstring of Message object。它说,

  

消息内容是一个名为.content的字典,而reply_channel是一个可选的额外属性,表示用于回复此消息的最终用户的频道,如果有意义的话。

您需要设置" reply_channel"在你发送的词典中。

message = {
    'text': json.dumps(payload),
    'reply_channel': 'websocket.receive'
}

希望有所帮助