I have the following phoenix channel that handle an incoming message, broadcasts it and then updates the channel instance's socket
state:
defmodule MyApp.MyChannel do
use MyApp.Web, :channel
def join("topic", _payload, socket) do
{:ok, socket}
end
def handle_in("update", %{"new_number" => number_}, socket) do
broadcast socket, "update", %{"new_number" => number_}
{:noreply, assign(socket, :current_number, number_)}
end
...
end
I am trying to test the behavior of the handle_in("update", ...)
function via this test case:
test "should broadcast new number and update the relevant instance's socket state", %{socket: socket} do
push socket, "update", %{"new_number" => 356}
assert_broadcast "update", %{"new_number" => 356}
## This is testing against the old state
## which is going to obviously fail
assert socket.assigns[:current_number] == 356
end
The issue here is that I can't find a way to get the new updated socket
state inside the test case.
There is no assert_socket_state
function in the Phoenix.ChannelTest
module and I can't find any function allowing to get the newest socket state
I thought about defining a handle_call
or a handle_info
that returns the socket state but this means that I will have to get the channel's pid in order to call them.
I thought about defining a handle_in
for this purpose but I don't want to put in my channel with an introspection tool that is going to be available in production.
How can I get the updated socket
in the test case, after pushing the message?
The socket
state contains a channel_pid
entry that basically contains the pid
of the channel.
The previous combined with the :sys.get_state/1
function which takes the pid
of a GenServer and returns its most recent state
is the key!
Example, given a socket
state inside a test case:
:sys.get_state(socket.channel_pid).assigns[:current_number]
Credit goes to Dogbert for their comment on the question.