I’m trying to test a session delete action but I can’t manage to make it pass.
Here is the stacktrace I receive
** (ArgumentError) cannot convert nil to param
stacktrace:
(phoenix) lib/phoenix/param.ex:67: Phoenix.Param.Atom.to_param/1
(moosely) web/router.ex:1: Moosely.Router.Helpers.session_path/4
test/controllers/session_controller_test.exs:48: (test)
Here is my test code
test "deletes the user session", %{conn: conn} do
user = Repo.get_by(User, %{username: "test"})
conn = delete conn, session_path(conn, :delete, user)
refute get_session(conn, :current_user)
assert get_flash(conn, :info) == "Signed out successfully!"
assert redirected_to(conn) == page_path(conn, :index)
end
And here is the controller action
def delete(conn, _) do
conn
|> delete_session(:current_user)
|> put_flash(:info, "Signed out successfully!")
|> redirect(to: page_path(conn, :index))
end
As a note: the delete action works perfectly, or it looks like so, in the UI but I can’t trust that until I have some tests passing.
it’s a long shot, but is it possible that Repo.get_by(User, %{username: "test"})
returns nil
? In cases like that I prefer to call get_by!
so that the test will fail early
3 Likes
I piped the result into IO.inspect
, it does indeed return nil
. Then I used get_by!
and I finally understood where the problem was.
I have a setup block in which I define the User object with multiple attributes (such as username, password, email, etc) so the test was expecting the same username as the one I defined in the setup block.
What a rookie mistake, anyway thank you for pointing me towards the right direction!
1 Like
I have a setup block in which I define the User object with multiple attributes (such as username, password, email, etc) so the test was expecting the same username as the one I defined in the setup block.
btw, instead of inserting a record in the setup
block and the fetching it in tests, you can pass it around as test context:
setup do
user = Repo.insert!(%User{...})
{:ok, %{user: user}}
end
test "some test", c do
IO.inspect c.user
end
# you can also match on context:
test "some test", %{user: user} do
IO.inspect user
end
1 Like
This does indeed seem like a better alternative!
I will refactor my tests
1 Like