如何测试before_filter在Rails中使用RSpec正常工作

时间:2011-05-04 09:41:33

标签: ruby-on-rails rspec

我的ApplicationController中有一个check_user_access_control before_filter,用于检查已记录用户的角色和权限,然后才能通过。我正在尝试对它进行一些测试,但我找不到一个很好的方法。

对于简单的索引操作,我只是这样做:

it "allows access to mod" do
  login_as(Factory(:mod)) # this is a spec helper
  get :index
  response.code.should == "200"
end

它工作得很好。对于编辑/显示/创建和需要一些参数的其他操作,与数据库的交互以及运行后可能的重定向,它需要太多其他东西才能被存根。

有没有办法测试在before_filters之后是否调用了特定的操作?我正在寻找类似controller.should_receive(:action_name)(不起作用)的内容来替换{{ 1}}与...一致。

版本:rails 3.0.4和rspec 2.5

我尝试了另一种方法。我们在ApplicationController中有一个名为response.code.should == "200"的方法,我正在使用redirect_to_login进行检查并且有效。

虽然它正确检测到用户是否被允许,但它会存根方法,这意味着无论用户是否被允许,都会运行控制器操作。此外,行动取决于参数和数据库,我们不希望这样。

如果现在我使用controller.should_receive(:redirect_to_login)存储操作方法,则不会运行操作,但RSpec仍在查找模板。好吧,有些动作没有模板,只是以controller.stub!(:action_name)redirect_to :action => :somewhere_else结束,此时我们并不关心。

在排序方面,我现在需要找到一种让RSpec NOT 担心模板存在的方法。

3 个答案:

答案 0 :(得分:8)

当存根时,你仍然可以给出一个虚拟实现。在该实现中,您可以引发错误,确保所有执行都停止,或者您仍然执行重定向。

E.g。

controller.should_receive(:redirect_to_log) { redirect_to login_url }

controller.should_receive(:redirect_to_log) { raise StandardError.new('login error') }
expect { get :index }.to raise_error

有关详细信息,请查看精彩的rspec documentation

希望它有所帮助。

答案 1 :(得分:0)

扩展@nathanvda's answer

  

当存根时,你仍然可以给出一个虚拟实现。在该实现中,无论如何都要进行重定向。

您需要在块中指定controller

expect(controller).to receive(:redirect_to_log) { controller.redirect_to login_url }

RSpec有一个匹配器,也称为redirect_to,在查找方法时优先。直接在控制器上调用它就可以解决这个问题。

答案 2 :(得分:0)

最终解决方案,感谢nathanvda:

it "allows access to moderator" do
  login_as(Factory(:mod))
  controller.stub!(action) { raise "HELL" }

  controller.should_not_receive(:redirect_to_login)
  expect { get action }.to raise_error(/HELL/)
end

it "denies access to user" do
  login_as(Factory(:user))

  controller.should_receive(:redirect_to_login) { raise "HELL" }
  expect { get :index }.to raise_error(/HELL/)
end

张贴于https://gist.github.com/957565