如何最好地编写RSpec自定义匹配器来测试Rails应用程序中的访问控制

时间:2008-10-13 14:57:19

标签: ruby-on-rails testing rspec

好的,所以我没有编写一大堆访问控制规范,而是在我的许多规范文件中复制它们,而是希望创建一个自定义匹配器。所以不要这样:

describe "access control" do
  it "should prevent access by non-logged-in users"
  it "should prevent access by normal users"
  it "should prevent access by editor users"
  it "should prevent access by admin users"
  it "should allow access by super admin users"
end

我想做这样的事情:

lambda do
  get :index
end.should have_access_control(:allowed => [:super_admin], :disallowed => [:admin, :editor, :user])

我是否有任何关于如何做这样事情的例子或建议?

2 个答案:

答案 0 :(得分:2)

好的,I have found a method of achieving this,虽然它不使用自定义匹配器。在spec_helper.rb中包含以下代码:

def access_control (code, options={})
  options = {:allow => [], :disallow => []}.merge(options)

  options[:allow].each do |user|
    it "#{code} should allow #{user.to_s}" do
      login_as(user)
      eval code
      response.should_not redirect_to(login_path)
    end
  end

  options[:disallow].each do |user|
    it "#{code} should disallow #{user.to_s}" do
      login_as(user)
      eval code
      response.should redirect_to(login_path)
    end
  end
end

并按如下方式调用:

access_control("get :index", {:allow => [:super_admin], :disallow => [:quentin, :admin]})

然后,您可以使用它来构建应限制的方法的完整列表,以及限制它们的用户。

答案 1 :(得分:0)

我不同意你的解决方案。测试不应该是像这样分解重复的区域。它使测试更难以阅读,更难维护。此外,肯定有一个论点是duplication in tests can inform your design

在您列出的初始示例中,有5种不同的上下文应分别进行单独测试,并且能够一目了然地理解。你的解决方案虽然整洁,却会损害这两个目标。