Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

  • Blog Navigation
Testing Views by Not Testing Views: Or, The Presenter Pattern

Err The Blog asks: “What’s the best way to test views?”

I think the best way to test views is not to test views. Extract all logic from the view into a model or presenter where it can be unit tested. Your views are then mostly declarative and there’s minimal need to test them.

Here’s an example of the “presenter pattern”.

def create_or_destroy_friendship_link(friend)
  if current_user.friends_with?(friend)

You don’t need a special class to do a Presenter; a good old-fashioned layer of abstraction will do. The basic idea is to write all conditional+iterative view logic in such a way as to never call a Rails helper directly, or generate any HTML directly, or generate any strings directly. The logic merely delegates to other methods closer to the metal.

Tests then become fairly simple. Write tests of the higher-level conditional/iterative logic in terms of the lower-level methods:

describe FriendshipsHelper, '#create_or_destroy...' do
  it "renders create link when two users are not friends" do
    bob.should_not be_friends_with(users(:amy))
    create_or_destroy_friendship_link.should == create_friendship_link

This minimizes the need for view specs. I find in practice that a high percentage of view tests slow development down””they’re implemented not to aid development (since you typically debug views in-browser), but to prevent regression (i.e., they minimize the likelihood of introducing defects later). But since views are one of the most variable parts of a web application, regression tests are of the least value.

As a side note, I love integrate_views — not because I like to make assertions about the view in my controller tests, but because I hate mocks! I want a controller test to fail if I have a syntax error in my view!

  • I’ve thought of doing something like that, but with helpers instead of pushing the logic into a model (which sounds heretical to me) or a presenter (not so bad). So my two questions:

    • Why not helpers?
    • How do you integrate designers into the fold? Do your presenters then render partials that they can edit?

    Also, I’d be interested to see your approach all the way down, i.e. what does create_friendship_link look like?

  • nick

    I am a heretic, and I believe that putting “view logic” in the model is perfectly OK. Nevertheless, as Alex points out, the above example does none of that. To totally change the topic, Here is my anti-MVC rant:

    MVC is a sacred cow, but we rarely ask “why?” let alone “should?”. Firstly, Rails MVC is a bit of a joke; their are no objects in the view layer, the Controller layer is only vaguely analogous to Controllers in the GUI world, etc.

    Secondly, MVC is not necessarily the best fit for a web app. If you buy into the REST religion, you might think there are only two layers of abstraction–resources and representations.

    Thirdly, many of the most interesting GUI frameworks are not MVC. cf., Morphic which was invented with Self and is now used in Squeak.

    Fourthly, MVC has serious downsides with are rarely acknowledged, namely that there’s a) a parallel class hierarchy (often you simply have one view mapping to one model mapping to one controller), and b) if you want to (e.g.) render a heterogeneous list of model objects you need a factory to instantiate appropriate views; that factory needs to break polymorphism and manually dispatch on type.

    In short, MVC is stupid. Heresy, yes.

  • @Alex OK, I thought they were methods on the Presenters. Cool.

    As to the mythical ISD, I agree that finding someone who can go from IA and visual design all the way down to templates is rare, but not unpossible. I know one fellow who can do just that, and even into the depths of Rails controllers and models.

    On the other hand, front-end developers who are saavy with JS, HTML and CSS are often competent enough to deal with Rails views. Plus, they are far more numerous. Unless we make things hard for them by outputing HTML from helpers and whatnot, they can do everything they’re used to doing with a minimum of fuss. But if your helpers rely on partials, then everyone can have their cake, it seems to me.

  • Man you don’t even know how long I’ve waited for this since disabling my own Movable Type widget (that doesn’t work since Haloscan bypasses that code).

  • Generally speaking how do you test a javascript code that run in a view let’s say triggered by a click on a button.

    Frederic Torres
    Web Testing with C# or VB.NET

  • @Frederic:

    There are a couple of approaches. First, you can test the javascript in isolation using jsunit. To test the complete page integration, you can use a tool like Selenium. See Pivotal’s seleniumrc-fu project for an integrated package that makes it easy to use these tools ( )

    — Chad

Share This