授权导致膨胀的控制器测试

时间:2014-07-23 14:08:31

标签: ruby-on-rails functional-testing testunit

我有一个过滤器,可确保只有超级管理员才能访问特定操作:

before_action :require_super_admin

def index; end

在我的控制器测试中,我得到了:

test "should let super admin access index" do
  login_super_admin
  get :index
  assert_response :success
end

test "should NOT let normal admin access index" do
  login_normal_admin
  get :index
  assert_response :redirect
end

test "should NOT let user access index" do
  login_user
  get :index
  assert_response :redirect
end

test "should NOT let guest access index" do
  login_guest
  get :index
  assert_response :redirect
end

确保只有超级管理员才能访问索引的四项测试。有没有更好的测试方法?有没有人发现自己在做这种事情?每次我构建一个rails应用程序时都会遇到它。

2 个答案:

答案 0 :(得分:0)

您可以创建共享示例

shared_example "allow super admins" do |actions|
  actions.each do |action|
    it "should let super admin access #{action}" do
       login_super_admin
       get action.to_sym
       assert_response :success
    end
  end
end

shared example "deny non super admins" do |actions, users|
  actions.each do |action|
    users.each do |user|
      it "should let not let #{user} access #{action}" do
         send("login_#{user}")
         get action.to_sym
         assert_response :redirect
      end
    end
  end
end

在需要授权检查的测试中,您可以

it_behaves_like "allow super admins", ["index"]
it behaves_like "deny non super admins", ["index"], ["normal_admin", "user", "guest"]
PS:我没有测试过这个。这只是为了给你一个想法

答案 1 :(得分:0)

我的解决方案:

# Gemfile
gem 'shoulda-context'

# In test_helper.rb
class ActiveSupport::TestCase    
  def make_sure_authorization_kicks_in
    assert_redirected_to root_url
    assert_equal "You are not authorized to perform this action.", flash[:error]
  end
end

# In controller tests
context "NOT Super Admin" do    
  # saves a lot of typing 
  teardown { make_sure_pundit_kicks_in }

  context "just NORMAL ADMIN" do
    setup { login_normal_admin }
    should("NOT get index"){ get :index }          
    should("NOT get new"){ get :new }
  end

  context "just normal USER" do
    setup { login_user }
    should("NOT get index"){ get :index }          
    should("NOT get new"){ get :new }
  end
end

这更容易管理。