2016-08-15 46 views
3

我正在使用Django頻道@channel_session_user裝飾器(用於訪問Django的會話數據)。Django頻道使用者測試:「沒有reply_channel發送給消費者」

@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: No reply_channel sent to consumer; @channel_session can only be used on messages containing it.

頻道源的誤差is raised here

打印reply_channel返回None而不是包含正確的答覆通道名稱。

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

我忽略了一些明顯的東西?

回答

1

我認爲你不能只是簡單地打電話給消費者,因爲它具有修飾器@channel_session_user。你應該嘗試使用客戶端channels.tests規定。

from channels.tests import ChannelTestCase, Client 

然後使用類似這樣的測試功能

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

這是因爲您提供的「通道」對象的名字代表收到這個消息上通道內。查看Channel的init function

還要注意tests/base.py文件中的函數get_next_message。這裏的頻道參數是指在測試期間將消息發送到的(應答)信道。

要回答你的問題 - 在渠道/ message.py

看那docstring of Message object。它說,

The message content is a dict called .content, while reply_channel is an optional extra attribute representing a channel to use to reply to this message's end user, if that makes sense.

您需要在您發送的字典中設置「reply_channel」。

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

希望它可以幫助