Tous les tests Ruby soulevant: méthode non définie `authenticate 'pour nil: NilClass

132

La plupart de mes tests soulèvent les éléments suivants et je ne comprends pas pourquoi. L'appel de toutes les méthodes génère l'erreur «authenticate». J'ai vérifié le code s'il y avait une méthode appelée "authentifier" mais il n'y en a pas.

  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)>'

Le projet peut être trouvé là-bas => https://github.com/agilepandas/enki au cas où vous voudriez exécuter les tests vous-même.

Jeffrey W.
la source

Réponses:

74

Je sais que vous utilisez Rspec, mais vous pouvez rencontrer le même problème avec Test::Unit. Il vous suffit d'ajouter les assistants de test de conception àtest/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end
Tim Fletcher
la source
8

La réponse ci-dessus n'a pas fonctionné pour moi (RSpec 3.1)

Voir https://stackoverflow.com/a/21166482/1161743 pour une solution qui a fonctionné pour moi.

Vous devrez déconnecter un utilisateur anonyme avant de configurer des variables:

before :each do
  sign_out :user
end
Jonathan Lin
la source
1
Vérifiez également que vous n'avez pas inclus Devise :: TestHelpers plusieurs fois car cela peut causer des problèmes.
Joseph Siefers
8

dans RSpec

comme Jeffrey W. l'a mentionné, dans sa réponse ci - dessus -> pour définir ceci sur tous les contrôleurs:

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

cependant, si cela concerne une seule spécification, vous n'avez pas nécessairement besoin d'inclure des assistants de conception pour toutes les spécifications de vos contrôleurs, vous pouvez simplement inclure explicitement ces helpers dans ce bloc de description de contrôleur:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end
équivalent8
la source
2

J'ai vécu les mêmes échecs dans l'un de mes projets. Il utilise Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. Lorsque j'exécute toutes les spécifications ensemble, le problème est survenu. Lorsque j'ai exécuté les spécifications individuellement, elles ont réussi. J'ai ce qui suit inclus dans mon spec / spec_helper.rb:

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

J'ai ajouté ce qui suit à la première description de chaque fichier de spécifications défaillant. Cela n'a pas résolu le problème:

before :each do
  sign_out :user
end

Ni l'un ni l'autre n'a:

after :each do
  sign_out :user
end

En m'inspirant de la réponse à cette question de stackoverflow, j'ai couru différentes combinaisons de répertoires rspec ensemble pour découvrir lesquels pourraient interférer les uns avec les autres. À la fin, j'ai découvert que j'appelais:

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

quand j'ai changé toutes les occurrences de ceci en:

before(:each) do
  :
end

Toutes les spécifications sont passées sans échec:

undefined method `authenticate' for nil:NilClass

J'espère que cela aidera les autres.

Cathal Curtis
la source
0

Si vous travaillez avec des spécifications de vue, vous pouvez utiliser un stub de current_user. Cela remplace efficacement l' current_userassistant appelé depuis votre vue par tout ce qui est renvoyé. Voici comment avec 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
Pete
la source
-3

Il semble qu'il y ait des mises à jour du code source. ApplicationController spécifie qu'un authenticate_user!filtre doit être exécuté avant toute demande. Ce fil fournit des informations générales sur ses problèmes:

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

Essentiellement, la authenticate_user!fonction fait partie de Rails 3 (en utilisant la nouvelle devisefonctionnalité, dont je connais peu). Si l'application ne peut pas trouver le modèle utilisateur (soit en raison de problèmes d'espace de noms ou pour une raison quelconque), la méthode échouera. L'application "enki" à laquelle vous vous êtes connecté est désormais une application Rails 3. Il pourrait éprouver quelques douleurs de croissance lors de sa conversion.

Berin Loritsch
la source
2
Cette réponse est absurde à environ 99%.
max
-20

Ruby vous le dit, cette méthode #authenticaten'a pas encore été définie nil. Vous pouvez le faire facilement en:

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

Et l'erreur disparaîtra.

Boris Stitnicky
la source
1
ne faites pas ça. nil est nul, n'est pas un objet valide dans 90% des cas.
Tiago Peczenyj