views:

49

answers:

1

I've been writing RSpec tests for some Rails controllers and I've discovered a strong impulse to ensure that the Authlogic authentication is working properly. I also feel like I should be verifying that each action uses the same application-wide layout. However, writing tests for this behavior in every single action seems silly.

What I'd like to see are one-line matchers for filters and layouts, similar to Shoulda's matchers for associations and verifications. Unfortunately, no such matchers seem to be available (except for some Test::Unit macros for filters in this blog post). I'm tempted to just write them myself, but not being able to find anyone who's already done it makes me question whether or not a need for such matchers actually exists.

So my question is, how do you test your controllers' common behavior (if you test it at all), and would one-liner matchers testing filters and layouts be useful? Myself, I'm trying to decide between one-liners in the controller specs combined with speccing the filter explicitly, or just speccing the filter and ignoring the filters and layouts in the controllers (since they're only one line of code anyway).

A: 

I don't like the idea of writing specs for filters -- that seems too close to the implementation. If you had used TDD/BDD methods to build your controller from scratch, presumably you'd have written the action first, added some logic (e.g. to handle authentication) and then realized it should go into a filter instead. If your spec is along the lines of "Reject an index request if the current user is not the account user", your spec ought to be able to do something like (aircode):

current_user = Factory.create(:unauthorized)
controller.should_not receive(:index)
get :index
request.should redirect_to(some_safe_path)

And it doesn't matter whether the action is using a filter or not.

You can DRY up controller specs with Rspec macros. So (more hand-waving):

describe MyController do
  should_reject_anonymous(self)
  ...
end

module ControllerMacros
  def should_reject_anonymous(test_controller)
    describe test_controller, "Authentication" do
      it "rejects index" do
        test_controller.should_not_receive(:index)
        get :index
        response.should redirect_to(some_safe_path)
      end
    end
  end
end
zetetic
Ok, so the idea is to test for behavior but do it in a macro. Good idea. I didn't actually write the controllers, I'm just trying to spec them properly now that they've been dropped on my lap :) Would it be reasonable to pass all the actions in at once and do an "it" block for each? I could do something similar to verify the correct layout use. It seems as if this is too small and project-specific to be gem-worthy too, so that answers my "should I publish this" question :)
Matthew Phipps
Holy frijoles! Shoulda has a "render_with_layout" method... /me faints
Matthew Phipps