Alle Ruby-Tests lösen: undefinierte Methode `authenticate 'für nil: NilClass aus

132

Die meisten meiner Tests sprechen Folgendes an und ich verstehe nicht warum. Alle Methoden rufen den Fehler 'Authentifizierung' auf. Ich habe den Code überprüft, wenn es eine Methode namens "authentifizieren" gab, aber es gibt keine solche Methode.

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

Das Projekt finden Sie dort => https://github.com/agilepandas/enki, falls Sie die Tests selbst durchführen möchten.

Jeffrey W.
quelle

Antworten:

191

Diese Frage wurde auf Twitter von @MatthewClosson beantwortet

@jeffehh Sie müssen eine Datei spec / support / devise.rb erstellen, wie hier angegeben: https://github.com/plataformatec/devise#test-helpers , um die Testhelfer #ruby einzuschließen

Noch einmal vielen Dank.

Jeffrey W.
quelle
2
Protokollieren der tatsächlichen URL (anstelle von bit.ly): Lesen Sie auf der Entwicklerseite ( github.com/plataformatec/devise ) den Abschnitt "Testhelfer".
Zabba
74

Ich bin mir bewusst, dass Sie Rspec verwenden, aber Sie können auf dasselbe Problem mit stoßen Test::Unit. Sie müssen nur die Testhelfer hinzufügentest/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end
Tim Fletcher
quelle
8

Die obige Antwort hat bei mir nicht funktioniert (RSpec 3.1)

Unter https://stackoverflow.com/a/21166482/1161743 finden Sie eine Lösung, die für mich funktioniert hat.

Sie müssen einen anonymen Benutzer abmelden, bevor Sie Variablen einrichten:

before :each do
  sign_out :user
end
Jonathan Lin
quelle
1
Stellen Sie außerdem sicher, dass Sie Devise :: TestHelpers nicht mehrmals aufgenommen haben, da dies zu Problemen führen kann.
Joseph Siefers
8

in RSpec

wie Jeffrey W. in seiner obigen Antwort erwähnt hat -> um dies auf alle Controller einzustellen:

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

Wenn dies jedoch nur für eine Spezifikation relevant ist, müssen Sie nicht unbedingt Entwicklungshelfer in alle Controller-Spezifikationen aufnehmen. Sie können diese Helfer nur explizit in diesen einen Controller-Beschreibungsblock aufnehmen:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end
Äquivalent8
quelle
2

Ich hatte die gleichen Fehler in einem meiner Projekte. Es verwendet Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. Wenn ich alle Spezifikationen zusammen ausführe, ist das Problem aufgetreten. Wenn ich die Spezifikationen einzeln ausführte, bestanden sie. Ich habe Folgendes in meiner spec / spec_helper.rb enthalten:

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

Ich habe der ersten Beschreibung in jeder fehlerhaften Spezifikationsdatei Folgendes hinzugefügt. Das Problem wurde dadurch nicht behoben:

before :each do
  sign_out :user
end

Weder tat:

after :each do
  sign_out :user
end

Ich ließ mich von der Antwort auf diese Frage zum Stapelüberlauf inspirieren und führte verschiedene Kombinationen von rspec-Verzeichnissen zusammen aus, um herauszufinden, welche sich gegenseitig stören könnten. Am Ende stellte ich fest, dass ich anrief:

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

als ich alle Vorkommen davon geändert habe zu:

before(:each) do
  :
end

Alle Spezifikationen wurden ohne Fehler bestanden:

undefined method `authenticate' for nil:NilClass

Ich hoffe, das hilft anderen.

Cathal Curtis
quelle
0

Wenn Sie mit der Ansichtsspezifikation arbeiten, können Sie von stub current_user. Dies überschreibt effektiv den current_useraus Ihrer Sicht aufgerufenen Helfer mit dem, was zurückgegeben wird. So geht's mit 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
quelle
-3

Es sieht so aus, als ob es einige Aktualisierungen des Quellcodes gibt. Der ApplicationController gibt an, dass authenticate_user!vor jeder Anforderung ein Filter ausgeführt werden muss. Dieser Thread bietet Hintergrundinformationen zu Problemen:

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

Im Wesentlichen ist die authenticate_user!Funktion Teil von Rails 3 (unter Verwendung der neuen deviseFunktion, über die ich wenig weiß). Wenn die App das Benutzermodell nicht finden kann (entweder aufgrund von Namespace-Problemen oder aus irgendeinem Grund), schlägt die Methode fehl. Die von Ihnen verknüpfte "enki" -Anwendung ist jetzt eine Rails 3-Anwendung. Es könnte ein paar wachsende Schmerzen haben, wenn es sich umwandelt.

Berin Loritsch
quelle
2
Diese Antwort ist zu 99% Unsinn.
Max
-20

Ruby sagt Ihnen, dass diese Methode #authenticatenoch nicht definiert wurde nil. Sie können es einfach tun, indem Sie:

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

Und der Fehler wird verschwinden.

Boris Stitnicky
quelle
1
Bitte tu das nicht. nil ist nil, ist in 90% der Fälle kein gültiges Objekt.
Tiago Peczenyj