• CONTACT

TheTechnologist.TV

  • the column

Loading...
Loading...
Home › Blogs › Wolfram Arnold's blog

RSpec View testing: Mocking helpers vs. mocking controller methods

Wolfram Arnold — Tue, 05/12/2009 - 01:35

RSpec::Rails (I'm using version 1.2.2 as of this writing) has a really cool feature to test view templates. This is one of the features where RSpec really has a leg up on standard Rails functional tests.

You can test the view templates without the controller actions running, which has the nice side-effect that your actions and your views become less tightly coupled—and you're doing BDD, right?

Here is an example of testing a layout, you can do this without even relating to an action or a view template:

  describe 'layouts/application' do

    before(:each) do
      @admin = users(:uber)
      template.controller.stub!(:current_user).and_return(@admin)
      # Note: this wouldn't work, see below: template.stub!(:logged_in?).and_return(true)
      @admin.admin?.should be_true
    end

    it 'should show admin logo with link to admin_users' do
      render 'layouts/application'
      response.should have_tag 'div#headerContainer' do
        with_tag 'div#logo' do
          with_tag 'img', :count => 1
          with_tag "a[href=#{admin_users_path}]" do
            with_tag "img[src*=header_logo_admin.gif]"
          end
        end
      end
    end

  end

Consider that my layout has code such as this in it:

    <div id="headerContainer">
      <div id="header">
        <div id="logo">
          <% if logged_in? %>
            <% if admin? %>
              <%= link_to image_tag('header_logo_admin.gif'), admin_users_path %>
            <% else -%>
              ...
            <% end -%>
          <% else -%>
              ...
          <% end -%>
        </div>
      </div>
    </div>

Both the logged_in? and admin? methods are implemented in application.rb where they call current_user.

The point of my post today is to highlight the difference between:

    template.controller.stub!(:current_user).and_return(@admin)

and

    template.stub!(:logged_in?).and_return(true)

The latter is what the RSpec::Rails docs on view testing tell us to do. The catch is that this ONLY stubs out helpers. If that helper happens to call a controller method, as is the case here, then the current_user is no longer mocked and the test fails obscurely. In order to make the mock live on for calls to the controller code, you need to mock template.controller. This mock also works in the template directly, so I'm tempted to conclude the former version is more general and works to mock both helpers and controller methods. The price you pay is that your BDD is then no longer encouraging the helper/controller separation as strictly.

See also this post: https://rspec.lighthouseapp.com/projects/5645/tickets/541-error-stubbing...

  • controller
  • gif
  • rails
  • rspec
  • Wolfram Arnold's blog

AUDIT THE FED

Latest

Generative Art From The Math of The Rodin Vortex, The Fibonacci Spiral, and The Gielis Superformula
2 days 14 hours ago
An Historic Press Release
2 weeks 4 days ago
Tahrir Tilt Shift
2 weeks 5 days ago

Below The Fold

On "The Ascent of Money", A BBC Series on The History of Finance
6 weeks 4 days ago
The History of All Earth Ever, as A Drop of Water on The Sun (abstract)
6 weeks 4 days ago
FTC Deals FaceBook The Largest "Hump On The Wrist" In Silicon Valley History
8 weeks 2 days ago
In The 6 Months Since I Closed The Lab, 11|3L3V3N Happened
10 weeks 4 days ago
When Did I Become Dr Who?
39 weeks 1 day ago
more

Active Topics

  • Technology
  • Google
  • Android
  • iPhone
  • Entertainment

AUDIT THE FED

  • the column