While continuing my getting used to Elixir testing approaches venture I encountered a “scratch-my-head” type of issue when upon testing a piece of code that calls render(conn, ...)
I began receiving the
** (KeyError) key :phoenix_endpoint not found in: %{phoenix_recycled: true, plug_skip_ [...]
The test module does use MyAppWeb.ConnCase, async: true
. The ConnCase
is unmodified vanilla Phoenix one, which sets @endpoint
and builds conn
, just like in other test modules.
I can work the error around with
conn = conn |> put_private(:phoenix_endpoint, MyAppWeb.Endpoint)
but this smells to me. Any hints why do I have to do this? And/or what should I do instead?
An example of test giving this error:
test "clears ip address", %{conn: conn, user: user} do
# GIVEN an inactive user and an IP address of the connection stored in the database
assert IpAddress |> where([ipa], ipa.ip_address == ^conn.remote_ip) |> Repo.aggregate(:count) == 1
# WHEN calling user_login_success/2
conn = Session.user_login_success(conn, user)
# EXPECT the ip address record to be removed from the database
assert IpAddress |> where([ipa], ipa.ip_address == ^conn.remote_ip) |> Repo.aggregate(:count) == 0
end
The offending (triggering error) render()
is located in:
defp user_not_activated(conn, user) do
conn
|> put_session(:email, user.email)
|> put_view(MyAppWeb.UserView)
|> render(:not_activated, [conn: conn, activation_resent_at: user.last_activation_sent_at])
|> halt()
end
Setup for this block:
setup %{conn: conn} do
# No idea why the `put_private` is needed. IMHO shouldn't be
# as the @endpoint is set in the ConnCase, but without it
# I get: "** (KeyError) key :phoenix_endpoint not found in: %{phoenix_recycled: true, plug_skip_ [...]"
conn = conn
|> put_format("html")
|> put_private(:phoenix_endpoint, NvoiceWeb.Endpoint)
SecurityFixtures.fixture(conn.remote_ip)
%{user: AccountsFixtures.fixture(:user), conn: conn}
end