Все тесты Ruby вызывают: неопределенный метод `authenticate 'для 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, чтобы включить помощников тестирования devise #ruby

Еще раз спасибо.

Джеффри В.
источник
2
Регистрация фактического URL (вместо bit.ly): на странице разработки ( github.com/plataformatec/devise ) см. Раздел «Помощники по тестированию».
Zabba
74

Я знаю, что вы используете Rspec, но вы можете столкнуться с той же проблемой с Test::Unit. Вам просто нужно добавить помощников тестирования devise в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
equivalent8
источник
2

У меня были такие же неудачи в одном из моих проектов. Он использует Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. Когда я проверил все спецификации вместе, возникла проблема. Когда я проверял спецификации по отдельности, они прошли. В мой spec / 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

Вдохновленный ответом на этот вопрос о переполнении стека, я провел вместе разные комбинации каталогов 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% - чистая ерунда.
max
-20

Ruby говорит вам, что этот метод #authenticateеще не определен nil. Вы можете легко это сделать:

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

И ошибка исчезнет.

Борис Стиницкий
источник
1
пожалуйста, не делай этого. ноль ноль, не является допустимым объектом в 90% случаев.
Тьяго Печеный