Mocking/Stubbing partials and helper methods in RSpec view specs

16 Mar 2007

In my previous post I whined about not knowing how to mock/stub partials and helper methods in RSpec view specs. Now I have the answer and I’d like to thank the RSpec users mailing list and David Chelimsky for taking my phone call.

In short, it’s all about @controller.template

@controller.template.stub!(:a_helper_method).and_return(true)

Stubs out the appropriately named a_helper_method and returns true. You can mock it out also like so:

@controller.template.should_receive(:a_helper_method).
at_least(:once).and_return(true)

Which is like the stub except that it checks to see that a_helper_method was called at least once

For partials you do this:

@controller.template.should_receive(:render).
with(:partial => ‘form’, :locals => {:cookie => mock_cookie})

Which checks to make sure the partial _form.rhtml is rendered and that the view attempted to pass mock_cookie in as a local. Since I didn’t specify a return it will return nil and I don’t have to worry about what’s in the _form view (of course, I’ll spec it by itself). Cool.

There’s just one problem: You can’t mock/stub a partial inside a partial. Let’s say that inside _form is another partial and while I was specifying _form I wanted to mock it out like so:

@controller.template.should_receive(:render).
with(:partial => ‘piece_of_form’)

But later in the spec when I do this:

render :partial => ‘form’

I’m making a call to the template to render and it gets intercepted by the mocking framework! So not only do I get an error that the wrong thing was rendered (_form instead of _piece_of_form) but I’ve intercepted the call so I don’t get inside the view at all. Even if I were to expect the call to render _form I make inside the spec (which is weird) I wouldn’t be able to render the _form. Bummer.

Oh well, I got almost all of what I wanted.