2016-10-19 76 views
0

我一直在爲頻道的多頻道示例項目https://github.com/andrewgodwin/channels-examples/tree/master/multichat中的一位消費者嘗試創建測試。消費函數如下:Django頻道HttpClient測試錯誤

@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函數,它只是調用send和分開使用,就像我做的那樣。

2)我怎樣才能使它工作,使我不會得到用戶登錄錯誤?

回答

0

我真的找到了更多的挖掘後的答案。

1)send_and_consume與調用send然後consume有不同的行爲,因爲我在這裏使用HttpClient。 HttpClient從客戶端繼承,並有它自己的實現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... 

我希望這可以幫助遇到類似問題的人。