10

I have the following failure:

Failures:

  1) RelationshipsController creating a relationship with Ajax should increment the Relationship count
     Failure/Error: xhr :post, :create, relationship: { followed_id: other_user.id }
     NoMethodError:
       undefined method `authenticate!' for nil:NilClass
     # ./spec/controllers/relationships_controller_spec.rb:14:in `block (4 levels) in <top (required)>'
     # ./spec/controllers/relationships_controller_spec.rb:13:in `block (3 levels) in <top (required)>'

But it is very strange, if I visit the site, the thing works (the followers counter does increment if I click the Follow button:

enter image description here

And the weirdest thing is that there isn't any authenticate! method in relationships_controller_spec.rb:

require 'spec_helper'

describe RelationshipsController do

  let(:user) { FactoryGirl.create(:user) }
  let(:other_user) { FactoryGirl.create(:user) }

  before { sign_in user }

  describe "creating a relationship with Ajax" do

    it "should increment the Relationship count" do
      expect do
        xhr :post, :create, relationship: { followed_id: other_user.id }
      end.to change(Relationship, :count).by(1)
    end

    it "should respond with success" do
      xhr :post, :create, relationship: { followed_id: other_user.id }
      response.should be_success
    end
  end

  describe "destroying a relationship with Ajax" do

    before { user.follow!(other_user) }
    let(:relationship) { user.relationships.find_by_followed_id(other_user) }

    it "should decrement the Relationship count" do
      expect do
        xhr :delete, :destroy, id: relationship.id
      end.to change(Relationship, :count).by(-1)
    end

    it "should respond with success" do
      xhr :delete, :destroy, id: relationship.id
      response.should be_success
    end
  end
end

Neither in the controller:

class RelationshipsController < ApplicationController
  before_filter :authenticate_user!

  def create
    @user = User.find(params[:relationship][:followed_id])
    current_user.follow!(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end

  def destroy
    @user = Relationship.find(params[:id]).followed
    current_user.unfollow!(@user)
    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end
  end
end

What could be the problem?

(By the way, these test were made following the Ruby on Rails Tutorial. After that, I removed all the authentication system because I wanted to use Devise.)

alexchenco
  • 53,565
  • 76
  • 241
  • 413

2 Answers2

22

Setting config.include Devise::TestHelpers, :type => :controller no longer works in later versions of Devise. What you need to do is log out an anonymous user to set up the proper variables:

before :each do
  sign_out :user
end
max
  • 96,212
  • 14
  • 104
  • 165
  • 3
    If this no longer works , why is it still in the gem's read me? https://github.com/plataformatec/devise#test-helpers – JCC Apr 30 '14 at 15:19
  • 1
    That answer works for me. But I accidentally noticed that I have an extra `include Devise::TestHelpers` in some spec file (except the one in the `spec_helper.rb`), removing that solved the problem. Hope this helps someone. – freemanoid Sep 12 '14 at 20:43
  • 1
    @JCC its still in the gems readme because most open source developers have day jobs we need to get done. – max Jul 08 '15 at 21:37
  • @freemaniod found a duplicate include in my config also, and removing it solved the issue, thanks! – Joseph Siefers Sep 01 '15 at 20:15
15

I had to add this:

spec_helpers.rb:

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end
alexchenco
  • 53,565
  • 76
  • 241
  • 413
  • Awesome. Was confused as to why I was getting a random error in my controller specs but not unit or request. Thanks! – Alex Lynham Oct 16 '13 at 09:43
  • @papirtiger is there a solution if the above doesn't work, which doesn't seem to be working for me. – John Jan 15 '14 at 22:29
  • 1
    @John The line should be included AFTER `require 'rspec/rails'`. I put this in `spec/rails_helper.rb` and it works. – Gregorio Setti Sep 23 '15 at 09:08