Wszystkie testy Rubiego podnoszą: niezdefiniowaną metodę „uwierzytelniaj” dla nil: NilClass

132

Większość moich testów podnosi następujące wartości i nie rozumiem dlaczego. Wszystkie wywołania metod powodują błąd „uwierzytelniania”. Sprawdziłem kod, jeśli istniała metoda o nazwie „uwierzytelnianie”, ale nie ma takiej metody.

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

Projekt można znaleźć tam => https://github.com/agilepandas/enki na wypadek, gdybyś chciał samodzielnie przeprowadzić testy.

Jeffrey W.
źródło

Odpowiedzi:

74

Wiem, że używasz Rspec, ale możesz napotkać ten sam problem z Test::Unit. Musisz tylko dodać pomocników testowych dotest/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end
Tim Fletcher
źródło
8

Powyższa odpowiedź nie działa dla mnie (RSpec 3.1)

Zobacz https://stackoverflow.com/a/21166482/1161743, aby znaleźć rozwiązanie, które zadziałało dla mnie.

Przed skonfigurowaniem zmiennych musisz wylogować anonimowego użytkownika:

before :each do
  sign_out :user
end
Jonathan Lin
źródło
1
Sprawdź również, czy nie dołączyłeś Devise :: TestHelpers wiele razy, ponieważ może to powodować problemy.
Joseph Siefers
8

w RSpec

jak wspomniał Jeffrey W., w swojej odpowiedzi powyżej -> aby ustawić to dla wszystkich kontrolerów:

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

jeśli jednak dotyczy to tylko jednej specyfikacji, niekoniecznie musisz dołączać pomocników devise do wszystkich specyfikacji kontrolerów, możesz po prostu jawnie dołączyć te pomocniki do tego jednego bloku opisującego kontroler:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end
odpowiednik 8
źródło
2

Doświadczyłem tych samych niepowodzeń w jednym z moich projektów. Używa Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. Po uruchomieniu wszystkich specyfikacji pojawił się problem. Kiedy sprawdzałem specyfikacje indywidualnie, przeszły. Mam następujące informacje zawarte w mojej specyfikacji / spec_helper.rb:

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

Dodałem następujące elementy do pierwszego opisu w każdym pliku specyfikacji, w którym wystąpił błąd. To nie rozwiązało problemu:

before :each do
  sign_out :user
end

Żaden:

after :each do
  sign_out :user
end

Czerpiąc inspirację z odpowiedzi na to pytanie o przepływie stosu, uruchomiłem razem różne kombinacje katalogów rspec, aby dowiedzieć się, które z nich mogą ze sobą kolidować. W końcu odkryłem, że dzwonię:

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

kiedy zmieniłem wszystkie wystąpienia tego na:

before(:each) do
  :
end

Wszystkie specyfikacje przeszły bez błędu:

undefined method `authenticate' for nil:NilClass

Mam nadzieję, że to pomoże innym.

Cathal Curtis
źródło
0

Jeśli pracujesz ze specyfikacją widoku, możesz wyłączyć current_user. To skutecznie zastępuje current_userpomocnika wywołanego z twojego widoku tym, co zostanie zwrócone. Oto jak z 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
źródło
-3

Wygląda na to, że są aktualizacje kodu źródłowego. ApplicationController określa, że authenticate_user!przed jakimkolwiek żądaniem musi być uruchomiony filtr. Ten wątek zawiera podstawowe informacje dotyczące problemów z nim:

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

Zasadniczo authenticate_user!funkcja jest częścią Rails 3 (używa nowej devisefunkcji, o której niewiele wiem). Jeśli aplikacja nie może znaleźć modelu użytkownika (z powodu problemów z przestrzenią nazw lub z jakiegokolwiek powodu), metoda zakończy się niepowodzeniem. Aplikacja "enki", z którą się łączyłeś, jest teraz aplikacją Rails 3. Może odczuwać kilka bólów wzrostu podczas konwersji.

Berin Loritsch
źródło
2
Ta odpowiedź to w 99% czysty nonsens.
max
-20

Ruby mówi ci, że ta metoda #authenticatenie została niljeszcze zdefiniowana . Możesz to łatwo zrobić poprzez:

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

A błąd zniknie.

Boris Stitnicky
źródło
1
proszę, nie rób tego. nil jest nil, nie jest prawidłowym obiektem w 90% przypadków.
Tiago Peczenyj