Rails中的RSpec:如何跳过before_filter?

seb*_*ger 17 rspec ruby-on-rails before-filter separation-of-concerns

我正在尝试测试我的控制器并保持关注点的分离.

第一个问题是"谁能够执行哪个行动?"
我使用authlogic进行身份验证,使用be9的acl9进行授权.但这应该不重要,我所有的授权问题都是在a before_filter.我正在before_filter通过类似的东西测试这样的:

describe SomeModelsController, "GET to index (authorization)" do
  before(:each) do
    @siteadmin = mock_model(User)
    @siteadmin.stub!(:has_role?).with("siteadmin", nil).and_return(true)
  end

  it "should grant access to a siteadmin" do
    controller.should_receive(:current_user).at_least(:once).and_return(@siteadmin)
    get :index
    response.should be_success
  end
end
Run Code Online (Sandbox Code Playgroud)

这个规格工作得很好!

现在,第二个问题是"行动是否做了应该做的事情?"
这不涉及检查授权.最好/最干净的解决方案是将before_filter所有内容一起跳过,并执行以下操作:

describe SomeModelsController, "GET to index (functional)" do
  it "should find all Models" do
    Model.should_receive(:find).with(:all)
  end
end
Run Code Online (Sandbox Code Playgroud)

无需担心具有哪个角色的用户必须首先登录.现在我解决了这个问题:

describe SomeModelsController, "GET to index (functional)" do
  before(:each) do
    @siteadmin = mock_model(User)
    @siteadmin.stub!(:has_role?).with("siteadmin", nil).and_return(true)
    controller.stub!(:current_user).and_return(@siteadmin)
   end

  it "should find all Models" do
    Model.should_receive(:find).with(:all)
  end
end
Run Code Online (Sandbox Code Playgroud)

如果我现在决定我的siteadmin无权再访问索引操作,那么它不仅会破坏一个规范 - 即在这种情况下HAS要打破的规范 - 而且还会完全不相关的第二个规范.

我知道这基本上是一个小问题,但如果有人能想出一个(优雅的)解决方案,那就太好了!

Bal*_*ldu 34

要跳过之前的过滤器:

controller.class.skip_before_filter :name_of_method_used_as_before_filter
Run Code Online (Sandbox Code Playgroud)

一个警告(提到文档)是这只适用于方法参考过滤器,而不是过程.

或者,你可以存根 current_user.has_role?

describe SomeModelsController, "GET to index (functional)" do
  before(:each) do
    controller.current_user.stub!(:has_role?).and_return(true)
  end

  it "should find all Models" do
    Model.should_receive(:find).with(:all)
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 请注意,存根控制器.class将影响整个测试套件中该类的所有其他实例. (4认同)
  • @mkirk我们在生产应用程序的测试套件中遇到了这个问题.(测试随机失败,因为在调用跳过的测试之后,skip_before_action影响测试运行**).这浪费了几个小时的开发时间.我会推荐一个存根. (2认同)