我写了一个自定义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未定义,因此会抛出错误。
我还尝试了很多其他解决方案,但似乎都没有处理非控制器测试,因为它们都依赖于请求对象。有没有人有这些问题的经验,可以解释可能的解决方案?
提前致谢。