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
精彩评论