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.

Jeffrey W.
fonte

Respostas:

191

Esta pergunta foi respondida no Twitter por @MatthewClosson

@jeffehh Você precisa criar um arquivo spec / support / devise.rb conforme especificado aqui https://github.com/plataformatec/devise#test-helpers para incluir os auxiliares de teste de criação #ruby

Obrigado mais uma vez.

Jeffrey W.
fonte
2
Registrando o URL real (em vez de um bit.ly): na página do dispositivo ( github.com/plataformatec/devise ), consulte a seção "Test Helpers".
Zabba
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
Tim Fletcher
fonte
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
Jonathan Lin
fonte
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
equivalente8
fonte
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.

Cathal Curtis
fonte
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
Pete
fonte
-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.

Berin Loritsch
fonte
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á.

Boris Stitnicky
fonte
1
por favor não faça isso. nil é nulo, não é um objeto válido em 90% dos casos.
Tiago Peczenyj 24/03