Devise Test Helper - sign_in does not work

If you include the Confirmable module in your User model (or other devise-authenticatable model), then the test @user you create must be confirmed for the sign_in to take effect:

before :each do
  @user = FactoryGirl.create :user
  @user.confirm!
  sign_in @user
end

(I see that this wasn't your issue, but perhaps another reader shall benefit from it.)


For versions of Devise 4.2.0+, the Devise::TestHelpers have been deprecated. Instead, Devise::Test::ControllerHelpers should be used.

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

changelog


For the spec, make sure to include Devise::TestHelpers. To make it easy, in my spec/spec_helper.rb, I have:

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

which automatically includes it for all controller specs.

Also, you need to do this to get sign_in to work:

@request.env["devise.mapping"] = Devise.mappings[:user]
get :new

It is probably best to add @request.env["devise.mapping"] = Devise.mappings[:user] to your before(:each). (Note you can do this in your config if you don't want to do this for every controller).


For the current_user part, make sure you have a model User, where you call devise

class User < ActiveRecord::Base
  # call devise to define user_signed_in? and current_user
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable
  # though you don't have to include all these modules
end

Devise uses the call in the User model to define user_signed_in? and current_user in your controllers. The reason is that if you have:

class Admin < ActiveRecord::Base
  devise
end

then Devise will have methods admin_signed_in? and current_admin defined.


Looks like you solved this, judging by your code. I have had this happen before, and for some reason it gets me every time.

The rspec/rails scaffold for controller specs won't work with Devise::TestHelpers out of the box.

get :index, {}, valid_session

The valid_session call overwrites the session stuff that Devise sets up. Remove it:

get :index, {}

This should work!