开发者

Dynamically generating shared examples in RSpec 2?

开发者 https://www.devze.com 2023-03-09 05:14 出处:网络
I\'m trying to keep my specs DRY by creating a shared example group that performs the boilerplate checks for all admin controllers (all controllers under the Admin namespace of my project).I\'m strugg

I'm trying to keep my specs DRY by creating a shared example group that performs the boilerplate checks for all admin controllers (all controllers under the Admin namespace of my project). I'm struggling to figure out how to do it, since the shared example needs providing with the information about what actions and parameters to use. It should ideally present meaningful errors if a test fails (i.e. include the details of the action it was testing).

require 'spec_helper'

shared_examples "an admin controller" do

  before(:each) do
    @non_admin = User.make
    @admin = User.make(:admin)
  end

  context "as an admin user" do
    @actions.each do |action, params|

      specify "I should be able to access ##{action.last} via #{action.first}" do
        self.active_user = @admin
        send(action.first, action.last, params)

        response.status.should be_ok
      end

    end   
  end

  context "as a regular user" do
    @actions.each do |action, params|

      specify "I should开发者_Python百科 be denied access to ##{action.last}" do
        self.active_user = @non_admin
        send(action.first, action.last, params)

        response.status.should be 403
      end

    end   
  end

end

describe Admin::UserNotesController do

  @user = User.make
  @actions = { [:get, :index]   => { :user_id => @user.id },
               [:get, :new]     => { :user_id => @user.id },
               [:post, :create] => { :user_id => @user.id } }

  it_behaves_like "an admin controller"

end

This errors for the obvious reason that @actions is not visible to the shared example group. If I use let, this is only available in the context of an example, not in the context of the describe block. Any ideas?


Here's a much cleaner way that should work:

require 'spec_helper'

shared_examples "an admin controller" do |actions|
  context "as an admin user" do
    actions.each_pair do |action, verb|
      specify "I should be able to access ##{action} via #{verb}" do
        send(verb, action, :user_id => User.make(:admin).id)
        response.status.should be_ok
      end
    end   
  end

  context "as a regular user" do
    actions.each_pair do |action, verb|
      specify "I should be denied access to ##{action}" do
        send(verb, action, :user_id => User.make.id)
        response.status.should be 403
      end
    end   
  end
end

describe Admin::UserNotesController do
  it_behaves_like "an admin controller", { 
    :index  => :get,
    :new    => :get,
    :create => :post
  }
end

See http://relishapp.com/rspec/rspec-core/v/2-6/dir/example-groups/shared-examples for more information

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号