Writing the poll controller test
Since we're now experts on controller tests, let's start writing our poll controller test. Open up our test/vocial_web/controllers/poll_controller_test.exs file and let's write our first major test:
test "GET /polls", %{conn: conn} do
conn = get conn, "/polls"
assert html_response(conn, 200) =~ "My First Poll"
end
Then we'll run mix test and verify that our new test passes:
$ mix test
.....
Finished in 0.2 seconds
5 tests, 0 failures
Randomized with seed 169967
Fantastic! Remember that in our dummy object, we gave the poll a title of "My First Poll", so that's why that test is structured the way it is! One habit you’ll want to get into, especially as you’re starting out, is slightly changing tests to make sure that they fail when the assumptions change. In our case, let's change the text that we’re looking for to be something like "My Last Poll" and run that instead:
$ mix test
....
1) test GET /polls (VocialWeb.PollControllerTest)
test/vocial_web/controllers/poll_controller_test.exs:4
Assertion with =~ failed
code: assert html_response(conn, 200) =~ "My Last Poll"
left: "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <meta name=\"description\" content=\"\">\n <meta name=\"author\" content=\"\">\n\n <title>Vocial - The Social Voting App!</title>\n <link rel=\"stylesheet\" href=\"/css/app.css\">\n </head>\n\n <body>\n <div class=\"container\">\n <header class=\"header\">\n <h4>Logo</h4>\n </header>\n\n <p class=\"alert alert-info\" role=\"alert\"></p>\n <p class=\"alert alert-danger\" role=\"alert\"></p>\n\n <main role=\"main\">\n<h2>Poll: My First Poll</h2>\n\n <strong>Choice 1</strong>: 0 votes\n <br />\n <strong>Choice 2</strong>: 5 votes\n <br />\n <strong>Choice 3</strong>: 2 votes\n <br />\n </main>\n\n </div> <!-- /container -->\n <script src=\"/js/app.js\"></script>\n </body>\n</html>\n"
right: "My Last Poll"
stacktrace:
test/vocial_web/controllers/poll_controller_test.exs:6: (test)
Finished in 0.1 seconds
5 tests, 1 failure
Randomized with seed 477119
Exactly as expected! Change it back and then we'll clean up the structure of our test a little bit more:
test "GET /polls", %{conn: conn} do
poll = %{
title: "My First Poll",
options: [
{"Choice 1", 0},
{"Choice 2", 5},
{"Choice 3", 2}
]
}
conn = get conn, "/polls"
assert html_response(conn, 200) =~ poll.title
Enum.each(poll.options, fn {option, votes} ->
assert html_response(conn, 200) =~ option
assert html_response(conn, 200) =~ "#{votes} votes"
end)
end
This runs assertions against the expected title from our dummy poll's title and each of its options! Rerun our tests again and we should see a fully green test suite. Congratulations, you’ve just written your first successful controller test! The good news is that since we really didn't write any custom code for our Poll View, there’s nothing for us to write to add test coverage there.