View Specs: expectations or stubs on ActionView helpers

While adding Textile to a resource following the outside-in BDD process described in the RSpec Book I found myself wanting to put a should_receive expectation on ActionView::Helpers::TextHelper#textilize

This left me somewhat confused, as I wasn't sure what to stub, and the book doesn't cover this. Google also drew a blank.

sticking a <%= inspect %> in the view and looking at the page source revealed an instance of ActionView::Base, which makes sense but was somewhat elusive. It also showed a @controller reference, which itself contains a @template reference. A consequence of this is that in your view spec you can get at the template with @controller.template

It turns out that within a view spec #template provides the relevant object. Thanks to Tim Riley for pointing this out.

For example:

it "should textalize the teaser and extra_content" do
  @service = mock_model(Service, :null_object => true)
  @service.stub!(:teaser).and_return 'a teaser'

  template.stub!(:textilize).and_return "textalised teaser"
  template.should_receive(:textilize).with @service.teaser

  render
  response.should contain("textalised teaser")
end

This kind of stubbing is useful as it checks that the view is calling the textilize method, part of the api, correctly, not whether RedCloth (or some other texitle gem) is doing its thing. Stubbing like this will, if nothing else, speed up the spec execution. Testing with input/output examples for the textilized data could go in the view spec, but api testing at that level seems out of place to me. Of course it should be tested at some level, e.g. with Cucumber. YMMV.