我的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 担心模板存在的方法。
答案 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)
当存根时,你仍然可以给出一个虚拟实现。在该实现中,无论如何都要进行重定向。
您需要在块中指定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