Phoenix.ChannelTestでどのsocketに対するpushか区別する
例えば特定のchannelに2人が接続したらそれぞれに違うメッセージをpushするような何かを考える。
socket
をsocket/1
やsocket/3
でつくってsubscribe_and_join/4
すればテスト上でjoinまでできる。ただしassert_push/3
は引数にsocket
を与えられないので、2人のどちらに送られたものか判別できない。
なにか方法はないかIO.inspect socket
とかアレコレやっていると、join_ref
というのが使えそうに見える。
assert_push
の実装は以下のようになっていて
defmacro assert_push(event, payload, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout)) do quote do assert_receive %Phoenix.Socket.Message{event: unquote(event), payload: unquote(payload)}, unquote(timeout) end end
実体はassert_receive
なので、これを使うと
# 1人目 {:ok, socket} = UserSocket.connect(%{"user_id" => "u1"}, socket(UserSocket), %{}) {:ok, _, %{join_ref: join_ref1}} = socket |> subscribe_and_join(ChatChannel, "room:1", %{}) # 2人目 {:ok, socket} = UserSocket.connect(%{"user_id" => "u2"}, socket(UserSocket), %{}) {:ok, _, %{join_ref: join_ref2}} = socket |> subscribe_and_join(ChatChannel, "room:1", %{}) # 1人目に"hey", 2人目に"hello" assert_receive %Phoenix.Socket.Message{event: "hey", payload: %{}, join_ref: ^join_ref1} assert_receive %Phoenix.Socket.Message{event: "hello", payload: %{}, join_ref: ^join_ref2}
と書ける。パターンマッチなので^
を忘れずに。