How to test broadcast inside terminate/2?

For some reason, I want to broadcast a message when someone leaves a channel or disconnects due to some network issues.

I wrote this code:

defmodule MyAppWeb.SomeChannel do
  use MyAppWeb, :channel

  @impl true
  def terminate(_reason, socket) do
    broadcast(socket, "left", %{})
  end
end

And here’s the test:

test "broadcast when leave", %{socket: socket} do
  IO.inspect self()
  leave(socket)
  assert_broadcast("left", _)
end

When I ran this test, I got the following error with no additional detail:

#PID<0.875.0>
** (EXIT from #PID<0.875.0>) shutdown: :left

I tested my implementation using the Chrome websocket extension “WebSocket King Client”, and it works.

My question is, how to test broadcasting in terminate/2, or is there another way to implement this behavior that can be tested?

How can we broadcast something, after connection got terminated?!?

Perhaps a separate channel…

The documentation of Phoenix.Channel.terminate/2 says

Invoked when the channel process is about to exit.

So I suppose when this callback is called, the channel is not exited yet.

1 Like

I figured it out.

When testing a channel, it appears that the channel process is somehow linked to the process running the test. When the channel process exits with a non-normal reason, it crashes the test process as well.

So, all I have to is to make the test process trapping exit.

1 Like

Can you also post your solution. :smiley:

Just adding Process.flag(:trap_exit, true) inside the test case, or inside setup do ... end.

2 Likes