nil的未定义方法`authenticate':使用Devise在Rails中测试自定义OmniAuth策略时的NilClass

时间:2015-06-19 21:56:26

标签: ruby-on-rails ruby rspec devise omniauth

我写了一个自定义OmniAuth策略,我现在正试图围绕它编写Rspec测试,但我一直收到这个错误:

NoMethodError:
   undefined method `authenticate' for nil:NilClass
 # ./controllers/application_controller.rb:58:in `block in <class:ApplicationController>'
 # ./lib/omniauth/custom_strategy.rb:135:in `block in callback_phase'
 # ./lib/omniauth/custom_strategy.rb:119:in `callback_phase'
 # ./spec/lib/omniauth/custom_strategy_spec.rb:62:in `block (3 levels) in <top (required)>'

在深入研究Devise代码之后,我发现错误源自lib / devise / controllers / helpers.rb,其中current_user方法在ApplicationController中定义:

def current_#{mapping}
  @current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
end

在这种情况下,监狱长定义为:

def warden
  request.env['warden']
end

所以,在我的规范中,由于它不是控制器规范,我在自定义代码中创建了一个Rack应用程序(如下所示:https://github.com/mkdynamic/omniauth/blob/master/spec/omniauth/strategies/developer_spec.rb),如下所示:

#spec块之外:

RSpec.configure do |config|
  config.include Rack::Test::Methods
end

#在spec块内:

let(:app){ Rack::Builder.new do |b|
  b.use Rack::Session::Cookie
  b.use OmniAuth::Strategies::CustomStrategy
  b.run lambda{|env| [200, {}, ['Not Found']]}
end.to_app }

这里的问题是Rack :: Test :: Methods不包含请求对象,就像Rspec在其控制器测试中提供的那样。因此,request.env未定义,因此未定义warden。

我尝试包含Devise :: TestHelpers,如此处所述(All Ruby tests raising: undefined method `authenticate' for nil:NilClass),但由于@request未定义,因此会抛出错误。

我还尝试了很多其他解决方案,但似乎都没有处理非控制器测试,因为它们都依赖于请求对象。有没有人有这些问题的经验,可以解释可能的解决方案?

提前致谢。

0 个答案:

没有答案