18

I am having problem with rspec testing controller the devise authentication.

I have a following setup

I have included

config.include Devise::TestHelpers, :type => :controller

in my spec_helper.rb

In my merchants_controller_spec.rb

describe MerchantsController do
  before :each do
    @user = Factory(:user)
    @merchant = Factory(:merchant, :user_id => @user.id,:is_approved => false, :is_blacklisted => false)
    controller.stub!(:current_user).and_return(@user)
  end
  describe "GET index" do
    it "assigns all merchants as @merchants" do
      merchant = Factory(:merchant,:is_approved => true, :is_blacklisted => false)
      get :index
      assigns(:merchants).should eq([merchant])
    end
  end
end

My merchants_controller.rb

class MerchantsController < ApplicationController

  before_filter :authenticate_user!
  def index
    @merchants = Merchant.approved
    debugger
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @merchants }
    end
  end
end

I have a scope approved in merchant model

scope :approved, where(:is_approved => true, :is_blacklisted => false)

Now my problem is even though i stubbed current_user and returned @user as current_user, My merchants_controller index spec is failing. But if i comment out authenticate_user! then the spec passes,

without authenticate_user! the debugger of index action is caught but with authenticate_user! debugger is not caught.

I think there is problem in subbing current_user and i am not able to figure it out.

Help me out..

2 Answers 2

24

Have you read through the docs on github?:

Devise includes some tests helpers for functional specs. To use them, you just need to include Devise::TestHelpers in your test class and use the sign_in and sign_out methods. Such methods have the same signature as in controllers:

sign_in :user, @user   # sign_in(scope, resource)
sign_in @user          # sign_in(resource)

sign_out :user         # sign_out(scope)
sign_out @user         # sign_out(resource)
Sign up to request clarification or add additional context in comments.

2 Comments

I replaced controller.stub!(:current_user).and_return(@user) with sign_in @user but still doesn't solve my problem. I think user is still not authenticated as debugger inside index action is still not caught. Any ideas?
I wish I could upvote this twice. I had a nested Factory to create my admin, and I couldn't figure out why the user was being created but not logged in.
10

Another alternative

RSpec.describe YourController, :type => :controller do
  before do
    user = FactoryGirl.create(:user)
    allow(controller).to receive(:authenticate_user!).and_return(true)
    allow(controller).to receive(:current_user).and_return(user)
  end

  # rest of the code
end

2 Comments

This works for me, for ALL my tests. Guides at github.com/plataformatec/devise/wiki/… and github.com/plataformatec/devise/wiki/… works for one example, but not not whole suite.
Instead of stubbing authenticate_user!, I just used the above answer (sign_in @user method) and the second stub of your answer allow(controller).to receive(:current_user).and_return(user)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.