views:

70

answers:

2

I have a bunch of recurring tests for some of my controller actions, all of which require authentication. As a result, you end up seeing a lot of code like the following:

  describe "authentication requests" do
    it "should return 401 for unauthenticated :show" do
      get :show
      ...
    end

    it "should return 401 for unauthenticated :create" do
      post :create
      ...
    end
  end

Is there a better way to DRY this code up so that any action in the controller that needs authentication can be described in one test?

A: 

I'm not an rspec user, but you could do something like:

describe "authentication requests" do

  limited_access = [:show, :create]

  limited_access.each do |action|
    it "should return 401 for unauthenticated :#{action}" do
      get action
      ## assert response 401
    end
  end

end

Or to just have one test:

describe "authentication requests" do

  limited_access = [:show, :create]

  it "should return 401 for unauthenticated #{limited_access.to_sentence}" do
    limited_access.each do |action|
      get action
      ## assert response 401
    end
  end

end

Could add a spec_helper method to abstract it for you ... The possibilities are endless.

jenjenut233
+1  A: 

If you need to replicate the tests across controllers, you can use rspec macros. Create a spec/macros/controller_macros.rb with a method like so:

def should_return_401_for_unauthenticated(test_controller)
  describe test_controller, "authentication requests" do
    it "should return 401 for show" do
      get :show
      response.code.should == "401"
    end
    it "should return 401 for create" do
      post :create
      response.code.should == "401"
    end
  end
end

Then in each controller spec that needs the tests:

describe MyController do
    should_return_401_for_unauthenticated(self)
end
zetetic