How to test layout view?

I have a phoenix app where I use the following code to change the titles for my pages:

<title><%= if (@title), do: "#{@title} | Joe Sweeney", else: "Joe Sweeney" %></title>

Where Joe Sweeney is the default title (I have a simple plug which sets @title to nil by default). If a page wants to provide a custom title, I can just do this in the assigns.

However, I don’t know how to test this. I don’t want to test that a certain title is being set for every single page. I just want to test that LayoutView renders the correct <title> tag when @title is nil, and then when @title is assigned otherwise.

I tried testing this just by calling render_to_string(BlogWeb.PageView, "index.html", conn: conn, title: "Foo") on my home page / however this doesn’t work because it only returns the HTML from the PageView module, not the HTML from my LayoutView.

I also can’t seem to directly render LayoutView with render_to_string because it seems the LayoutView can’t be rendered without an actual template to render inside it (which is expected but I don’t know how to get around this to test just the layout view).

Does anyone know how I can test the layout view like I am trying to do? Thanks!

<title><%= title(assigns) %></title>
defmodule MyAppWeb.LayoutView do
    def title(%{title: title}), do: "#{@title} | Joe Sweeney"
    def title(_), do: "Joe Sweeney"

Now you can simply test the logic without even needing to render a view anywhere. You can test that the title is indeed rendered for any page, which uses the layout once.

1 Like

That seems like a good solution, I’m going to try it out :slight_smile: However I don’t think that its a bad thing to have to render a view in the test. It is a view test after all, so I feel like what the view renders HTML wise is just as important as the functions that it defines. I don’t really like changing my code just to make it more testable but it might be necessary here.

Also, this solution means that I could possibly forget the <title><%= title(assigns) %></title> line in my layout view, which the tests wouldn’t pick up on, which I don’t totally like.

1 Like

Sure, but you can just check any one page using that layout if the title is available and you won’t need to check the “business logic” of how the title is exactly formatted.

1 Like