2012-08-22 34 views
1

我有一个使用cancan的rails应用程序,并且我正在测试几种不同的角色。我正在寻找最干的方式来设置这些测试跨越几个控制器。这是用RSpec&Shoulda测试用户角色的正确DRY方式吗?

这是我迄今为止的简短版本。有一个更好的方法吗?它对我仍然感觉很重。

describe OrganizationsController do 
    render_views 

    before do 
    # User roles 
    @unauthenticated = User.new 
    @org_admin = Factory.create(:organization_admin) 
    @org_staff = Factory.create(:org_staff) 
    @customer = Factory.create(:customer) 
    @admin = Factory.create(:admin) 

    @organization = Factory.create(:organization) 
    @org_for_admin = Factory.create(:organization, :user_group_id => @org_admin.user_group_id) 
    @org_attr = FactoryGirl.attributes_for(:organization) 
    end 

    describe "GET 'show'" do 
    authorized = %w(org_admin admin org_staff customer) 
    not_authorized = %w(unauthenticated) 

    not_authorized.each do |u| 
     context "an organization by a user with role: #{u}" do 
     before do 
      user = instance_variable_get("@#{u}") 
      get :show, :id => @organization.id, :format => 'json' 
     end 
     it { should_not respond_with :success } 
     it { should respond_with :forbidden } 
     end 
    end 

    authorized.each do |u| 
     context "an organization by a user with role: #{u}" do 
     before do 
      user = instance_variable_get("@#{u}") 
      get :show, :id => @organization.id, :format => 'json', :token => user.token 
     end 
     it { should respond_with :success } 
     it { should render_template :show } 
     it { should respond_with_content_type(/json/) } 
     it { should assign_to(:organization).with_kind_of(Organization) } 
     end 
    end 
    end 

    describe "GET 'update'" do 
    authorized = [%w(admin organization), %w(org_admin org_for_admin)] 
    not_authorized = [%w(unauthenticated organization), %w(org_staff org_for_admin), %w(customer organization), %w(org_admin organization)] 
    not_authorized.each do |u, o| 
     context "an organization by a user with role: #{u}" do 
     before do 
      user = instance_variable_get("@#{u}") 
      organization = instance_variable_get("@#{o}") 
      put :update, :id => organization.id, :organization => @org_attr, :format => 'json' 
     end 
     it { should_not respond_with :success } 
     it { should respond_with :forbidden } 
     end 
    end 

    authorized.each do |u, o| 
     context "an organization by a user with role: #{u}" do 
     before do 
      user = instance_variable_get("@#{u}") 
      organization = instance_variable_get("@#{o}")   
      put :update, :id => organization.id, :organization => @org_attr, :format => 'json', :token => user.token 
     end 
     it { should respond_with :success } 
     it { should render_template :update } 
     it { should respond_with_content_type(/json/) } 
     it { should assign_to(:organization).with_kind_of(Organization) } 
     end 
    end 
    end 
end 

或者,我应该使用康康舞匹配器和移动这些类型的能力测试到模型规格,只是有一个成功的和每个控制器动作被禁止的考验吗?在反模式/文体建议方面对我的测试的任何其他评论也是受欢迎的。

谢谢!

回答

3

wiki描述了“痛点”你的感觉:

它可能很难在 功能/集成度进行全面的测试用户权限,因为经常有许多分支 可能性。

..如果您想要独立于Ability类中的内容来测试控制器行为 ,很容易 用任何您想要的行为来删除该能力。

def setup 
    @ability = Object.new 
    @ability.extend(CanCan::Ability) 
    @controller.stubs(:current_ability).returns(@ability) 
end 

test "render index if have read ability on project" do 
    @ability.can :read, Project 
    get :index 
    assert_template :index 
end 

好问题。我经常自己想这个。下一次,我将尝试维基的建议。

+0

这看起来更清洁。谢谢! – paulnsorensen

相关问题