测试客户端通道是否收到消息

Test that the client channel receives a message

在我的 Phoenix 应用程序中,我有一个通道被 MyApp.Endpoint.broadcast(topic, type, data) 污染了。这个广播是由一些外部源事件触发的(在我的例子中是 RabbitMQ。)

场景是:MQ 客户端收到一条消息⇒ 应用程序将它广播给特定频道的所有订阅者。我在测试中使用本地本地 RabbitMQ 服务器。

我将如何测试它? Phoenix.ChannelTest.assert_broadcast/3“进程邮箱为空。”.

不起作用

assert_reply 需要引用并且被调用为 assert_reply Phoenix.Channel.socket_ref(socket), ... 也不起作用,引发 “(ArgumentError) 只能为已加入的套接字生成套接字引用使用推送参考。

我肯定广播确实触发了(在 devtest 环境中用 wsta 检查过)

所以,我的问题是:如何在 Phoenix 测试套件中测试由某些外部源触发的广播事件?


当我尝试按照@Kociamber 的建议从测试进程订阅相应的频道时,它以同样的方式失败 “进程邮箱为空。”

test "handle RabbitMQ message", %{socket: _socket} do
  Phoenix.PubSub.subscribe MyApp.PubSub, "channel:topic"
  payload = %{foo: "bar"}
  RabbitMQ.trigger!(payload)
  assert_receive ^payload, 3_000
end

我发现以下方法对频道(和广播)测试很有用,看起来它也适用于您。首先,您需要使用 Phoenix.PubSub.subscribe/2, define your expected message (payload) value and then use assert_receive/2 订阅您的主题以对其进行测试:

assert_receive ^expected_payload

您可能还想在使用 Phoenix.PubSub.unsubscribe/2

完成测试后取消订阅该主题

这是向频道成员广播消息的测试,可能会对您有所帮助

 test "new_msg event broadcasts new message to other channel members",
  %{socket1: socket1, user1: user1, group: group} do
     {:ok, _, socket1} = subscribe_and_join(socket1, "groups:#
    {group.slug}")

   @endpoint.subscribe("groups:#{group.slug}")

   ref = push socket1, "new_msg", %{text_content: "Hello, World!"}
   assert_reply ref, :ok

   assert_broadcast "new_msg", data

   assert data.user_id == user1.id
   assert data.text_content == "Hello, World!"
 end