如何测试Phoenix套接字是否已终止?

时间:2016-10-05 16:48:47

标签: elixir phoenix-framework

我正在寻找一种测试套接字被终止的方法。测试中的代码执行此操作:

def handle_in("logout", _payload, socket) do
  {:stop, :logout, socket |> assign(:user, nil)}
end

我的测试代码(改编自http://elixir-lang.org/getting-started/try-catch-and-rescue.html#exits)执行此操作:

test "logout terminates the socket", %{socket: socket} do
  try do
    push socket, "logout"
  catch
    huh -> IO.puts("Caught something #{IO.inspect huh}")
    :exit, what -> IO.puts("Caught :exit #{IO.inspect what}")
  end
  assert_receive {:DOWN, monitor_ref, _, :normal}
end

但是当我运行测试时,我得到了这个:

1) test logout without login terminates the socket (Main.AuthChannelTest)
   test/channels/auth_channel_test.exs:47
   ** (EXIT from #PID<0.505.0>) :logout

.....09:06:41.139 [error] GenServer #PID<0.507.0> terminating
** (stop) :logout

我应该如何 测试套接字关闭?

2 个答案:

答案 0 :(得分:3)

当您监控的进程发生故障时发送的消息为{:DOWN, ref, :process, pid, reason},因此

  1. assert_receive

  2. 中应该有5个元组
  3. 如果您想与原因:normal匹配,则应以:normal为原因终止。如果你这样做,你就不必捕获任何退出信号(如果你想退出:logout,请参见下文)。

  4. 以下适用于我:

    def handle_in("logout", _payload, socket) do
      {:stop, :normal, socket |> assign(:user, nil)}
    end
    
    test "...", %{socket: %{channel_pid: channel_pid} = socket} do
      monitor_ref = Process.monitor(channel_pid)
      push socket, "logout", %{}
      assert_receive {:DOWN, ^monitor_ref, _, _, :normal}
    end
    

    如果由于某种原因想要退出使用:logout的原因的套接字,那么除了:normal以外,您还必须将退出设置为陷阱导致退出信号被发送到链接到进程的所有进程,并且在测试中,运行测试的进程链接到socket.channel_pid。以下作品:

    def handle_in("logout", _payload, socket) do
      {:stop, :logout, socket |> assign(:user, nil)}
    end
    
    test "...", %{socket: %{channel_pid: channel_pid} = socket} do
      Process.flag(:trap_exit, true)
      monitor_ref = Process.monitor(channel_pid)
      push socket, "logout", %{}
      assert_receive {:DOWN, ^monitor_ref, _, _, :logout} 
    end
    

答案 1 :(得分:0)

通过Elixir Slack频道收到了一个很好的答案:

修改测试代码以捕获退出信号。以下是更新后的测试工作:

test "logout terminates the socket", %{socket: socket} do
  Process.flag(:trap_exit, true)
  push socket, "logout"
  socket_pid = socket.channel_pid
  assert_receive {:EXIT, ^socket_pid, :logout}
end

请注意,这仍有控制台日志噪音,因此我已将退出原因更改为:normal,并且一切都很安静。