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

标签 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

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

最佳答案

当你监控的进程宕机时发送的消息是{:DOWN, ref, :process, pid, reason},所以

  1. 您应该在 assert_receive

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

以下对我有用:

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

关于elixir - 如何测试 Phoenix 套接字是否已终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39879632/

相关文章:

elixir - 添加一个唯一字段并填充它

药剂Ecto : How to validate foreign key constraint?

struct - Plug.Conn.Unfetched 未实现 Access 行为

elixir - 带有 do-block 的关键字参数

elixir - __info__/1 与 :exports in Elixir 1. 6

metaprogramming - 在 Elixir 1.2 或更高版本中重新整合协议(protocol)

elixir - 获取指定索引对象时出错

elixir - Postgres-Phoenix/Elixir安装错误

elixir - 使用 Ecto 变更集删除尾随和前导空格

postgresql - 如何使用 ecto 更新或插入多行? (更新插入)