我可能会以错误的方式去做。我首先做的是规格,BDD / TDD并且碰到了碰撞。
我有这个application_controller_spec.rb
require "spec_helper"
describe ApplicationController do
describe "current_user" do
it "should return nil if no one is logged in" do
subject.current_user.should be_nil
end
it "should return currently logged in user" do
hash = {user_id: "my_id"}
subject.should_receive(:session).and_return hash
subject.current_user.should == "my_id"
end
end
end
完全正常 没有 protected
关键字。
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
protected
def current_user
session[:user_id]
end
end
启用protected
,我收到此错误消息
NoMethodError: protected method `current_user' called for #<ApplicationController:0x2a90888>
我应该可以使用helper_method进行测试...有什么建议吗?
答案 0 :(得分:13)
helper_method
使视图中的方法可用,而不是控制器。
如果您确实需要从控制器规范访问该方法,可以使用send
:
subject.send(:current_user).should be_nil
但您可能想要考虑测试非公开方法是否有意义,或者是否更好地使用视图规范进行测试。或者首先是否需要保护该方法。看看Devise和Authlogic如何为他们的current_user
方法实施测试也是有益的。
答案 1 :(得分:2)
虽然距离最初的问题还有一段时间,但也许有人觉得这很有用。
您可以创建ApplicationController
的匿名子类,并在其中公开受保护的方法。无需send()
方法。
以下是如何操作:
describe ApplicationController, type: :controller do
controller do
def current_user
super
end
end
...
it 'should return nil if no one is logged in' do
expect(controller.current_user).to be_nil # (or whatever)
end
end
来源是this SO回答。