Усі тести Ruby: підвищення невизначеного методу `автентифікувати 'для nil: NilClass


132

Більшість моїх тестів викликають наступне, і я не розумію, чому. Усі виклики методів викликають помилку "автентифікувати". Я перевірив код, чи існував метод під назвою "автентифікувати", але такого методу немає.

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

Проект можна знайти там => https://github.com/agilepandas/enki, якщо ви хочете запустити тести самостійно.

Відповіді:


191

На це запитання відповів у Twitter @MatthewClosson

@jeffehh Вам потрібно створити файл spec / support / devise.rb, як зазначено тут https://github.com/plataformatec/devise#test-helpers, щоб включити помічників для тестових розробок #ruby

Ще раз дякую


2
Реєстрація фактичної URL-адреси (замість bit.ly): на сторінці розробки ( github.com/plataformatec/devise ) див. Розділ «Тест-помічники».
Забба

74

Я знаю, що ви використовуєте Rspec, але ви можете зіткнутися з цією самою проблемою Test::Unit. Вам потрібно лише додати помічників для тестуванняtest/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end

8

Наведена відповідь не спрацювала для мене (RSpec 3.1)

Дивіться https://stackoverflow.com/a/21166482/1161743 про рішення, яке працювало для мене.

Перед налаштуванням змінних вам потрібно буде вийти з анонімного користувача:

before :each do
  sign_out :user
end

1
Також переконайтеся, що ви не включали Devise :: TestHelpers кілька разів, оскільки це може спричинити проблеми.
Джозеф Сіферс

8

в RSpec

як згадував Джеффрі, у своїй відповіді вище -> щоб встановити це всім контролерам:

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

однак, якщо це стосується лише однієї специфікації, вам не обов’язково потрібно включати помічників для всіх своїх контролерів, ви можете явно включити ці помічники в один описуючий блок контролера:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end

2

Я відчував ті самі невдачі в одному зі своїх проектів. Він використовує Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. Коли я запускаю всі технічні характеристики разом, виникла проблема. Коли я керував специфікаціями окремо, вони проходили. У моїй специфікації / spec_helper.rb включено таке:

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

Я додав наступне до першого опису у кожному несправному специфікаційному файлі. Це не вирішило проблему:

before :each do
  sign_out :user
end

Ні:

after :each do
  sign_out :user
end

Отримавши натхнення у відповіді на це запитання про stackoverflow, я побіг різні комбінації каталогів rspec разом, щоб з’ясувати, які з них можуть заважати один одному. Зрештою я виявив, що дзвоню:

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

коли я змінив усі випадки цього на:

before(:each) do
  :
end

Усі характеристики пройшли безвідмовно:

undefined method `authenticate' for nil:NilClass

Я сподіваюся, що це допоможе іншим.


0

Якщо ви працюєте з специфікаціями перегляду, ви можете заглушити current_user. Це фактично перекриває current_userпомічника, викликаного з вашого погляду, з тим, що повернеться. Ось як з 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

-3

Схоже, є деякі оновлення вихідного коду. ApplicationController вказує, що authenticate_user!перед будь-яким запитом потрібно виконати фільтр. Цей потік містить деякі відомості про проблеми, пов'язані з ним:

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

По суті, authenticate_user!функція є частиною Rails 3 (використовуючи нову deviseфункцію, про яку я мало знаю). Якщо додаток не може знайти модель користувача (через проблеми з простором імен або з якоїсь причини), метод не вдасться. Додаток "enki", з яким ви пов’язали, тепер є програмою Rails 3. Він може відчувати кілька зростаючих болів, коли перетворюється.


2
Ця відповідь становить приблизно 99% чистої дурниці.
макс

-20

Рубі каже вам, що цей метод #authenticateще не визначений nil. Ви можете легко це зробити:

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

І помилка піде.


1
будь ласка, не робіть цього. нуль є нульовим, не є дійсним об'єктом у 90% випадків.
Tiago Peczenyj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.