RSpec和受保护的方法,current_user的控制器规范

时间:2011-03-04 14:32:25

标签: ruby-on-rails rspec

我可能会以错误的方式去做。我首先做的是规格,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进行测试...有什么建议吗?

2 个答案:

答案 0 :(得分:13)

根据{{​​3}},

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回答。