te_chris
How to test a live_session on_mount handler that sets assigns
I’m running into an edge case with phoenix testing. I’ve got an on_mount handler behaving like a plug which creates a db session for a given client:
defmodule SgWeb.InitSessionId do
@moduledoc """
Adds the DB session ID to the assigns
"""
import Phoenix.Component
alias Sg.Sessions
def on_mount(:default, _params, %{"client_id" => client_id}, socket) do
session =
case Sessions.get_session_by_client_id(client_id) do
nil ->
{:ok, session} = Sessions.create_session(%{client_id: client_id})
session
existing_session ->
existing_session
end
{:cont, assign(socket, session_id: session.id)}
end
end
However, whenever I try to test this as one would a plug, the assign function blows up and tells me I need to use render_component. I understand the logic, generally, but there has to be a way around this - I’m literally following a use case described in the docs in this instance (Phoenix.LiveView — Phoenix LiveView v0.19.5). Is there an easy way to mock a socket/assigns without triggering the exceptions?
Marked As Solved
sodapopcan
Have you tried this?
socket = %Phoenix.LiveView.Socket{}
It seemed to do the trick for me.
Also Liked
sodapopcan
I should be clear that I was just testing out your example and think Chris’ suggestion is the way to go.
Personally, I forgo unit testing these hooks and just test their effects in each LiveView they’re used in. I make a helper for this, kind of like how phx_gen_auth does with its generated register_and_log_in_user test helper. But obviously if you want a unit test that’s absolutely fine, I’m just sharing!
Speaking of phx_gen_auth, it actually does generate unit tests for its hooks that look like your tests! For example:
test "authenticates current_user based on a valid user_token ", %{conn: conn, user: user} do
user_token = Accounts.generate_user_session_token(user)
session = conn |> put_session(:user_token, user_token) |> get_session()
{:cont, updated_socket} =
UserAuth.on_mount(:ensure_authenticated, %{}, session, %LiveView.Socket{})
assert updated_socket.assigns.current_user.id == user.id
end







