2012-08-22 67 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

相關問題