“undefined method `env' for nil:NilClass” in 'setup_controller_for_warden' error when testing Devise using Rspec

后端 未结 10 2010
陌清茗
陌清茗 2020-12-09 14:31

I\'m trying to create a spec for a sign out flow by using factorygirl to create a user and then use Devise\'s sign_in method to authenticate the user, then use

相关标签:
10条回答
  • 2020-12-09 15:02

    My Devise version is 4.2.0 so I just included

    config.include Devise::Test::ControllerHelpers, type: :controller
    

    in my rails helper file.

    Alternatively you can use the same in your spec as

    include Devise::Test::ControllerHelpers
    
    0 讨论(0)
  • 2020-12-09 15:04

    I was having this problem when trying to sign_in a user in a before hook:

    before(:context) do
      create(:skill, name: 'Google Maps API'.downcase)
      user = create(:user)
      sign_in user
    end
    

    Placing sign_in inside the before hook leads to:

    Failure/Error: sign_in user
    
     NoMethodError:
       undefined method `env' for nil:NilClass
    

    But placing it inside an example works fine:

    shared_examples_for('an authenticated resource.') do
      describe 'An authenticated request' do
        it "responds with HTTP status OK" do
          user = create(:user)
          sign_in user
          make_request
          expect(response).to have_http_status(:ok)
        end
      end
    end
    

    But this can be improved, placing the sign_in into a before(:example) that will also work:

    context 'allow search by keyword' do
      let!(:skill){ create(:skill, name: 'Google Maps API'.downcase) }
      let!(:user) { create(:user) }
    
      before(:example) { sign_in user }
    
      it 'finds matching records' do
        get :search, name: "Google Maps API", format: :json
        expect(assigns(:skills).size).to be(1)
      end
      it 'finds records that start with keyword'
      it 'finds records that end with keyword'
      it 'finds records that contains keyword'
    end
    
    0 讨论(0)
  • 2020-12-09 15:10

    Here's my solution:

    class ActiveSupport::TestCase
      # all the normal stuff
    end
    
    class ActionController::TestCase
      include Devise::TestHelpers    
    end
    
    0 讨论(0)
  • 2020-12-09 15:10

    The correct syntax for Rails 5 / Devise (4.2.0) is

    RSpec.configure do |config|
      config.include Devise::Test::ControllerHelpers, :type => :controller
    end
    
    • Devise::TestHelpers are deprecated so use Devise::Test::ControllerHelpers
    • :type => :controller - to limit only for controllers and not models for example.
    0 讨论(0)
  • 2020-12-09 15:10

    For the sake of being complete, with Rails 5 and RSpec I have run into similar issues when using the latest helpers, as they need to be set explicitly with the type when not used as a superclass.

    So if you find yourself receiving there errors in your model tests there's a pretty good chance the type is not set.

    Here's what I use in the spec_helper:

      config.include Devise::Test::ControllerHelpers, type: :controller
      config.include Devise::Test::ControllerHelpers, type: :view
      config.include Devise::Test::IntegrationHelpers, type: :feature
    

    I know that the docs do mention this, but there are times when you may run across an older blog that gives you an older approach, or upgrading from an older setup, and next thing you know this happens.

    0 讨论(0)
  • 2020-12-09 15:12

    Apparently there are issues with Devise::TestHelpers and integration testing, so perhaps that's the problem here.

    https://github.com/plataformatec/devise (mentioned in README, Issues, etc.; also see related SO questions):

    These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session;

    0 讨论(0)
提交回复
热议问题