Testing a Channel
Learn how to write test cases for phoenix channels.
We'll cover the following...
The Phoenix Channel example we’ve provided in the NotSkull sample app, LobbyChannel, has limited functionality. We won’t exhaustively show how to use all of the test macros included in Phoenix as we test ChannelTest, but we’ll cover enough so that we’ll understand how to use all of them.
Understanding the channel
Let’s take a look at the file:
#file path -> lib/not_skull_web/channels/lobby_channel.ex#add this code at the indicated place mentioned in comments of lib/not_skull_web/#channels/lobby_channel.ex in the playground widgetalias NotSkull.GameEngine.Game@impl truedef join("lobby:lobby", _payload, socket) do{:ok, socket}end@spec broadcast_new_game(Game.t()) :: :ok | :errordef broadcast_new_game(%Game{current_phase: :joining} = game) doNotSkullWeb.Endpoint.broadcast!("lobby:lobby", "new_game_created", %{game_id: game.id})enddef broadcast_new_game(_) do:errorend
This file provides just two functions, join/3
and broadcast_new_game/1
. In the join/3
function, found on line 7 is a required callback for the Channel framework and simply returns a socket, assuming it’s been called with valid parameters. As a result, we’ll cover this functionality in our test as part of our setup. On line 13, there is broadcast_new_game/1
, which will broadcast a map containing the ID of a new game to any client connected to the Channel.
There’s one more clause for broadcast_new_game/1
that returns an error if either something other than a %Game{}
struct is passed in or if the value of the game struct’s current_state is something other than :joining
.
Defining the test
We’ll need a happy path test, and error tests for each state that falls into the error clause. Create a new test file at test/not_skull_web/channels/lobby_channel_test.exs
and populate it with the following code for the test file:
#file path -> test/not_skull_web/channels/lobby_channel_test.exs#add this code at the indicated place mentioned in comments of test/not_skull_web/#channels/lobby_channel_test.exs in the playground widgetdefmodule NotSkullWeb.LobbyChannelTest douse NotSkullWeb.ChannelCasealias NotSkullWeb.{LobbyChannel, UserSocket}describe "broadcast_new_game/1" dosetup douser_id = Factory.uuid(){:ok, _, socket} =UserSocket|> socket("user_socket:#{user_id}", %{user_id: user_id})|> subscribe_and_join(LobbyChannel, "lobby:lobby")%{socket: socket}end
Typical tests for a Phoenix Channel will start with the assumption that the user has already connected to the WebSocket through the code in ...