All Ruby tests raising: undefined method `authenticate' for nil:NilClass

Ruby on-RailsRubyTestingRspecDevise

Ruby on-Rails Problem Overview


Most of my tests are raising the following and I don't understand why. All methods call raise the 'authenticate' error. I've checked the code if there was a method called "authenticate" but there is no such method.

  1) Admin::CommentsController handling GET to index is successful
     Failure/Error: get :index
     undefined method `authenticate!' for nil:NilClass
     # ./spec/controllers/admin/comments_controller_spec.rb:9:in `block (3 levels) in <top (required)>'


  124) PostsController handling GET for a single post should render show template
     Failure/Error: get :show, :year => '2008', :month => '01', :day => '01', :slug => 'a-post'
     undefined method `authenticate' for nil:NilClass
     # ./app/controllers/application_controller.rb:18:in `set_current_user_for_model'
     # ./spec/controllers/posts_controller_spec.rb:131:in `do_get'
     # ./spec/controllers/posts_controller_spec.rb:140:in `block (3 levels) in <top (required)>'

The project can be found over there => https://github.com/agilepandas/enki in case you'd like to run the tests your self.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

This question has been answered on Twitter by @MatthewClosson

> @jeffehh You need to create a > spec/support/devise.rb file as > specified here https://github.com/plataformatec/devise#test-helpers to > include the devise test helpers #ruby

Thanks once again.

Solution 2 - Ruby on-Rails

I'm aware you're using Rspec but you can run into this same issue with Test::Unit. You just need to add the devise test helpers to test/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end

Solution 3 - Ruby on-Rails

in RSpec

as Jeffrey W. mentioned, in his answer above -> to set this to all controllers:

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

however, if this is relevant to just one spec, you don't necessarily need to include devise helpers to all your controllers specs, you can just explicitly include those helpers in that one controller describe block:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end

Solution 4 - Ruby on-Rails

The above answer did not work for me (RSpec 3.1)

See https://stackoverflow.com/a/21166482/1161743 for a solution that worked for me.

You will need to log out an anonymous user before setting up variables:

before :each do
  sign_out :user
end

Solution 5 - Ruby on-Rails

I was experiencing the same failures in one of my projects. It is using Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. When I run all specs together the problem occurred. When I ran the specs individually, they passed. I have the following included in my spec/spec_helper.rb:

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

I added the following to the first describe in each failing spec file. This did not resolve the problem:

before :each do
  sign_out :user
end

Neither did:

after :each do
  sign_out :user
end

Taking inspiration from the answer to this stackoverflow question, I ran different combinations of rspec directories together to find out which ones could be interfering with each other. In the end I discovered I was calling:

before() do #note no :each passed to before
  :
end

when I changed all occurrences of this to:

before(:each) do
  :
end

All the specs passed without the failure:

undefined method `authenticate' for nil:NilClass

I hope this is of help to others.

Solution 6 - Ruby on-Rails

If you're working with view spec, you can stub of current_user. This effectively overrides the current_user helper called from your view with whatever is returned. Here's how with rspec-3.2.3:

RSpec.describe "projects/show", type: :view do
  before(:each) do
    allow(view).to receive(:current_user).and_return(FactoryGirl.create(:user))
  end

  it "renders attributes in <p>" do
    render
    expect(rendered).to match(/whatever you want to regex match here/)
  end
end

Solution 7 - Ruby on-Rails

It looks like there are some updates to the source code. The ApplicationController specifies that there needs to be an authenticate_user! filter run before any request. This thread provides some background on issues with it:

http://groups.google.com/group/plataformatec-devise/browse_thread/thread/f7260ebe2d9f7316?fwc=1

Essentially, the authenticate_user! function is part of Rails 3 (using the new devise feature, of which I know little about). If the app can't find the User model (either because of namespace issues or whatever reason) then the method will fail. The "enki" application you linked to is now a Rails 3 application. It could be experiencing a few growing pains as it converts over.

Solution 8 - Ruby on-Rails

Ruby is telling you, that method #authenticate has not been definded on nil yet. You can do it easily by:

def nil.authenticate!
  puts "Bingo! Nil is now authentic!"
end

And the error will go away.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeffrey W.View Question on Stackoverflow
Solution 1 - Ruby on-RailsJeffrey W.View Answer on Stackoverflow
Solution 2 - Ruby on-RailsTim FletcherView Answer on Stackoverflow
Solution 3 - Ruby on-Railsequivalent8View Answer on Stackoverflow
Solution 4 - Ruby on-RailsJonathan LinView Answer on Stackoverflow
Solution 5 - Ruby on-RailsCathal CurtisView Answer on Stackoverflow
Solution 6 - Ruby on-RailsPeteView Answer on Stackoverflow
Solution 7 - Ruby on-RailsBerin LoritschView Answer on Stackoverflow
Solution 8 - Ruby on-RailsBoris StitnickyView Answer on Stackoverflow