One of the things that immediately appealed to me about Phoenix coming from Rails its views. Once I started creating functions in my views that returned HTML, however, I was instantly confused about how to test them.
I was making a function in my LayoutView
that rendered a link for a site’s
navigation. It included some css framework boilerplate stuff and would also add
the is-active
class if the current path matched the link’s path. I wanted to
write a test like this:
If you try to run these tests, though, you will be surprised. The reason is that
the link
function does not return a string. Instead, it will return something
like:
This is a tuple marked as :safe
(meaning it has already been html escaped)
with the second element being an IO list. You can read about why it is an IO
list instead of a string in this interesting post by Big Nerd
Ranch.
So, how should this be tested? You could try to match on the IO list, but I
think it is a lot easier to reason about tests against an html string. I looked
through the tests for Phoenix.HTML on
github and came across the
Phoenix.HTML.safe_to_string/1
function. This takes a tuple with :safe
as its
first element and an IO list as its second one and returns a string of html.
This is exactly what we were hoping for. Use that in your tests and they will
work as expected:
I hope this helps you write tests for your views in Phoenix apps. I can tell you from experience that if you let too much of your view code go untested (or let a bunch of logic sneak into your templates) you will be scared to make sweeping changes to your view-related code — so get testing!