I wrote a custom OmniAuth strategy and am now trying to write Rspec tests around it, but I keep getting this error:
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)>'
After digging through the Devise code, I found that the error was originating in lib/devise/controllers/helpers.rb, where the current_user method gets defined in ApplicationController:
def current_#{mapping}
@current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
end
In this case, warden is defined as:
def warden
request.env['warden']
end
So, in my spec, since it's not a controller spec, I put in custom code to create a Rack app (as seen here: https://github.com/mkdynamic/omniauth/blob/master/spec/omniauth/strategies/developer_spec.rb) like so:
# Outside of the spec block:
RSpec.configure do |config|
config.include Rack::Test::Methods
end
# Inside the spec block:
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 }
The problem here is that the Rack::Test::Methods don't include a request object, like Rspec provides in its controller tests. So, request.env is not defined and therefore warden is not defined.
I tried including Devise::TestHelpers, as described here (All Ruby tests raising: undefined method `authenticate' for nil:NilClass), but since @request is not defined, it throws an error.
I've also tried many other solutions, but none seem to deal with non-controller tests, since they all rely on a request object. Has anyone had experience with these issues and can shed some light on possible solutions?
Thanks in advance.