Testing the Happy Path for Create

Learn how to write a happy path test for the create endpoint.

Let’s take a look at the create endpoint. This is the endpoint hit by the form rendered by our previous endpoint for new.

Controller

Let’s take a look at the code and discuss what we’ll need to test:

Press + to interact
#file path -> lib/not_skull_web/controllers/user_controller.ex
def create(conn, %{"user" => user_params}) do
case Accounts.create_user(user_params) do
{:ok, user} ->
Email.send_welcome(user)
conn
|> put_session(:user_id, user.id)
|> put_flash(:info, "Your account was created successfully!")
|> redirect(to: Routes.user_path(conn, :show, user))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "new.html", changeset: changeset)
end
end

There’s branching logic in this function, depending on the success of Accounts.create_user(user_params). As a result, we know that we’ll need at least two tests, a happy path test and an error test.

Happy path test

There are four new code elements that we haven’t tested before:

  1. Sending an email (an outside call as a side effect)
  2. Setting values in the session
  3. Setting the flash
  4. Redirecting a call.

Let’s write our happy path test first since it’s where we’ll cover these. Open up the test file user_controller_test.exs and add a new describe block and test as follows:

Press + to interact
#file path -> test/not_skull_web/controllers/user_controller_test.exs
describe "POST /users" do
test "success: creates_user, redirects to show page when user is created",
%{conn: conn} do
params = Factory.atom_params(:user)
expect_email_to(params.email)
conn = post(conn, Routes.user_path(conn, :create), user: params)
assert %{id: id} = redirected_params(conn)
assert redirected_to(conn) == Routes.user_path(conn, :show, id)
assert %{"user_id" => ^id} = get_session(conn)
assert get_flash(conn, :info) =~ "success"
user_from_db = Repo.get(User, id)
fields_to_check = Map.keys(params) -- [:password]
assert_values_for(
expected: params,
actual: user_from_db,
fields: fields_to_check
)
assert user_from_db.password
end
end

Let’s see the details of the test:

  • It inherits a Plug.Conn from the test setup.
  • On line 5, we’re getting valid parameters from our factory.
  • Line 7 calls out to a
...