Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 capybara to click the "Sign Out" link.

I'm getting (what seems to me to be) a strange error when I run the spec:

Failures:

  1) Sign out flow successfully redirects to the welcome index (root)
     Failure/Error: Unable to find matching line from backtrace
     NoMethodError:
       undefined method `env' for nil:NilClass
     # /home/vagrant/.rvm/gems/ruby-2.0.0-p576/gems/devise-3.4.1/lib/devise/test_helpers.rb:24:in `setup_controller_for_warden'

Finished in 0.00226 seconds (files took 3.32 seconds to load)
1 example, 1 failure

Here's the spec:

require 'rails_helper'

describe "Sign out flow" do

  include Devise::TestHelpers

  describe "successfully" do
    it "redirects to the welcome index (root)" do
      user = create(:user)
      sign_in user


      within '.user-info' do
        click_link 'Sign Out'
      end

      expect(current_path).to eq root_path
    end
  end
end

And my user.rb factory:

FactoryGirl.define do
  factory :user do
    name "Fake User"
    sequence(:email, 100) { |n| "person#{n}@example.com" }
    password "helloworld"
    password_confirmation "helloworld"
    confirmed_at Time.now
  end
end

The error seems to be triggered simply from the line include Devise::TestHelpers, as I've tried commenting out the entire content of the spec and still get the same error.

I thought the Devise test helpers would work out of the box; did I miss some configuration? Thanks.

like image 326
jpalmieri Avatar asked Dec 04 '14 01:12

jpalmieri


5 Answers

In Rails 5 you must include Devise::Test::IntegrationHelpers instead Devise::Test::ControllerHelpers:

# rails_helper.rb
config.include Devise::Test::IntegrationHelpers, type: :feature

See more:

  • https://github.com/plataformatec/devise/issues/3913#issuecomment
  • https://github.com/plataformatec/devise/pull/4071
like image 187
user1519240 Avatar answered Oct 25 '22 11:10

user1519240


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;

like image 30
TK-421 Avatar answered Oct 25 '22 10:10

TK-421


FWIW it seems like the issues have been fixed, however I ran into the issue after not reading the documentation well enough.

This was our code:

RSpec.configure do |config|
  ...  
  config.include Devise::TestHelpers
  ...
end

This means every test will include the test helpers, including models. This wound up being the issue for us. Should we have read the documentation closer we would have noticed Devise suggests limiting it to only controllers with:

RSpec.configure do |config|
  ...  
  config.include Devise::TestHelpers, type: :controller
  ...
end

This solved the issue for us. All tests passing :)

like image 18
NoahNoahNoah Avatar answered Oct 25 '22 11:10

NoahNoahNoah


Here's my solution:

class ActiveSupport::TestCase
  # all the normal stuff
end

class ActionController::TestCase
  include Devise::TestHelpers    
end
like image 12
Will Taylor Avatar answered Oct 25 '22 10:10

Will Taylor


I meet the same error on rails 5. Here's my solution

spec/rails_helper.rb

RSpec.configure do |config|
  config.include Devise::TestHelpers, type: :controller
  config.include Devise::TestHelpers, type: :view
  config.include Warden::Test::Helpers
end

spec/controllers/your_controller_spec.rb

RSpec.describe YourController, type: :controller do
  before(:all) do
  user = FactoryGirl.create(:user)
  login_as user, scope: :user
end

it "#index" do
  get "index"
  expect(response).to render_template(:index)
  expect(response).to have_http_status(200)
end

$ rspec --tag focus

Run options: include {:focus=>true}
DashboardController
#index
Finished in 3.9 seconds (files took 3.5 seconds to load)
1 example, 0 failures
like image 9
Ray Lee Avatar answered Oct 25 '22 10:10

Ray Lee