2011-05-27 66 views
8

我試圖通過創建一個共享示例組來執行所有管理控制器(我的項目的Admin命名空間下的所有控制器)的樣板檢查,以保持我的規範DRY。我很難找出如何去做,因爲共享示例需要提供有關使用哪些操作和參數的信息。如果測試失敗,它應該理想地呈現出有意義的錯誤(即包括它正在測試的動作的細節)。在RSpec 2中動態生成共享示例?

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 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 

這個錯誤的原因很明顯,@actions對共享示例組不可見。如果我使用let,則僅在示例的上下文中提供,而不適用於describe塊的上下文。有任何想法嗎?

回答

27

這裏有一個應該工作更清潔方式:

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 

瞭解更多信息

+1

http://relishapp.com/rspec/rspec-core/v/2-6/dir/example-groups/shared-examples這是輝煌的,謝謝!沒有什麼像刪除代碼:) – d11wtq 2011-05-27 15:30:24