我写了一个自定义的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未定义,因此会抛出错误 .

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

提前致谢 .