David - Musings of an SRE

DRY up your Devise Logins in RSpec

Tired of instantiating a def setup that logins a user for ever rspec controller that will require devise logins?

In order to DRY your login mechanisms in Devise:

  1. Create a external library that contains your various login strategies. I chose to put mine in /spec/support/controller_macros.rb. You can name the file anything you want. Make sure you modify the module name as well if you do so.
module ControllerMacros
  def login_admin
      @request.env["devise.mapping"] = Devise.mappings[:admin]
      user = FactoryGirl.build(:user)
      user.save!(:validate => false)
      user.add_role(:admin)
      sign_in user
      @current_user = user
  end

  def login_user
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.build(:user)
      user.save!(:validate => false)
      sign_in user
      @current_user = user
  end
end
  1. Create a reference to it in your RSpec Helper
# spec/spec_helper.rb
RSpec.configure do |config|

  config.include Devise::TestHelpers, :type => :controller
  config.include ControllerMacros, :type => :controller
  1. You’re done, now you can run login_user in any of your specs:
# some spec file
  it 'if question_option already exists, a new question_option should not be created' do
    login_user
    ...

I chose to do a config.include ControllerMacros instead of an config.extend as recommended in the source below because I’d like to explicitly tell each of my test cases whether to login or not.

Source: Devise Wiki