Todos os testes Ruby levantando: método indefinido `authenticate 'para nil: NilClass


132

A maioria dos meus testes está levantando o seguinte e não entendo o porquê. Todos os métodos chamados geram o erro 'autenticar'. Eu verifiquei o código se havia um método chamado "autenticar", mas não existe esse método.

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

O projeto pode ser encontrado por lá => https://github.com/agilepandas/enki , caso você queira executar os testes por conta própria.

Respostas:



74

Estou ciente de que você está usando o Rspec, mas pode enfrentar esse mesmo problema Test::Unit. Você só precisa adicionar os auxiliares de teste de planejamento paratest/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end

8

A resposta acima não funcionou para mim (RSpec 3.1)

Consulte https://stackoverflow.com/a/21166482/1161743 para obter uma solução que funcionou para mim.

Você precisará desconectar um usuário anônimo antes de configurar as variáveis:

before :each do
  sign_out :user
end

1
Além disso, verifique se você não incluiu o Devise :: TestHelpers várias vezes, pois isso pode causar problemas.
Joseph Siefers 01/09/2015

8

no RSpec

como Jeffrey W. mencionou, em sua resposta acima -> para definir isso para todos os controladores:

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

no entanto, se isso for relevante para apenas uma especificação, você não precisará necessariamente incluir auxiliares planejados em todas as especificações de seus controladores, mas apenas explicitamente incluir esses auxiliares no bloco de descrição de um controlador:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end

2

Eu estava enfrentando as mesmas falhas em um dos meus projetos. Está usando Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. Quando executo todas as especificações, o problema ocorreu. Quando eu corri as especificações individualmente, elas foram aprovadas. Eu tenho o seguinte incluído no meu spec / spec_helper.rb:

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

Eu adicionei o seguinte à primeira descrição em cada arquivo de especificação com falha. Isso não resolveu o problema:

before :each do
  sign_out :user
end

Nem:

after :each do
  sign_out :user
end

Inspirando-me na resposta a essa pergunta do stackoverflow, executei diferentes combinações de diretórios rspec para descobrir quais poderiam estar interferindo entre si. No final, descobri que estava ligando:

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

quando alterei todas as ocorrências disso para:

before(:each) do
  :
end

Todas as especificações foram aprovadas sem a falha:

undefined method `authenticate' for nil:NilClass

Espero que isso ajude os outros.


0

Se você estiver trabalhando com especificações de exibição, poderá fazer o stub de current_user. Isso efetivamente substitui o current_userauxiliar chamado da sua exibição pelo que for retornado. Veja como, com o 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

Parece que existem algumas atualizações no código fonte. O ApplicationController especifica que é necessário que um authenticate_user!filtro seja executado antes de qualquer solicitação. Este tópico fornece alguns antecedentes sobre problemas com ele:

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

Essencialmente, a authenticate_user!função faz parte do Rails 3 (usando o novo deviserecurso, sobre o qual sei pouco). Se o aplicativo não conseguir encontrar o modelo de Usuário (devido a problemas no namespace ou por qualquer motivo), o método falhará. O aplicativo "enki" ao qual você vinculou agora é um aplicativo do Rails 3. Pode haver algumas dores de crescimento à medida que se converte.


2
Esta resposta é cerca de 99% de absurdo puro.
máximo

-20

Ruby está lhe dizendo, esse método #authenticateainda não foi definido nil. Você pode fazer isso facilmente:

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

E o erro desaparecerá.


1
por favor não faça isso. nil é nulo, não é um objeto válido em 90% dos casos.
Tiago Peczenyj 24/03
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.