所有 Ruby 测试引发:未定义的方法 `authenticate' for nil:NilClass

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4308094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:44:11  来源:igfitidea点击:

All Ruby tests raising: undefined method `authenticate' for nil:NilClass

ruby-on-railsrubytestingrspecdevise

提问by Jeffrey W.

Most of my tests are raising the following and I don't understand why. All methods call raise the 'authenticate' error. I've checked the code if there was a method called "authenticate" but there is no such method.

我的大多数测试都提出以下问题,我不明白为什么。所有方法调用都会引发“身份验证”错误。我检查了代码是否有一种称为“身份验证”的方法,但没有这样的方法。

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

The project can be found over there => https://github.com/agilepandas/enkiin case you'd like to run the tests your self.

该项目可以在那里找到 => https://github.com/agilepandas/enki,以防您想自己运行测试。

回答by Jeffrey W.

This question has been answered on Twitter by @MatthewClosson

@MatthewClosson 在 Twitter 上回答了这个问题

@jeffehh You need to create a spec/support/devise.rb file as specified here https://github.com/plataformatec/devise#test-helpersto include the devise test helpers #ruby

@jeffehh 您需要按照此处指定的方式创建 spec/support/devise.rb 文件https://github.com/plataformatec/devise#test-helpers以包含设计测试助手 #ruby

Thanks once again.

再次感谢。

回答by Tim Fletcher

I'm aware you're using Rspec but you can run into this same issue with Test::Unit. You just need to add the devise test helpers to test/test_helper.rb

我知道您正在使用 Rspec,但您可能会遇到与Test::Unit. 您只需要将设计测试助手添加到test/test_helper.rb

class ActiveSupport::TestCase
  include Devise::TestHelpers
end

回答by Jonathan Lin

The above answer did not work for me (RSpec 3.1)

上面的答案对我不起作用(RSpec 3.1)

See https://stackoverflow.com/a/21166482/1161743for a solution that worked for me.

有关对我有用的解决方案,请参阅https://stackoverflow.com/a/21166482/1161743

You will need to log out an anonymous user before setting up variables:

在设置变量之前,您需要注销匿名用户:

before :each do
  sign_out :user
end

回答by equivalent8

in RSpec

在 RSpec

as Jeffrey W. mentioned, in his answer above-> to set this to all controllers:

正如 Jeffrey W. 在上面回答中提到的那样-> 将其设置为所有控制器:

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

however, if this is relevant to just one spec, you don't necessarily need to include devise helpers to all your controllers specs, you can just explicitly include those helpers in that one controller describe block:

但是,如果这仅与一个规范相关,则您不一定需要将设计助手包含到所有控制器规范中,您只需在该控制器描述块中明确包含这些助手即可:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end

回答by Cathal Curtis

I was experiencing the same failures in one of my projects. It is using Ruby 2.0.0-p598, Rails 3.2.21, RSpec 2.99. When I run all specs together the problem occurred. When I ran the specs individually, they passed. I have the following included in my spec/spec_helper.rb:

我在我的一个项目中遇到了同样的失败。它使用 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

I added the following to the first describe in each failing spec file. This did not resolve the problem:

我在每个失败的规范文件中的第一个描述中添加了以下内容。这并没有解决问题:

before :each do
  sign_out :user
end

Neither did:

也没有:

after :each do
  sign_out :user
end

Taking inspiration from the answer to thisstackoverflow question, I ran different combinations of rspec directories together to find out which ones could be interfering with each other. In the end I discovered I was calling:

这个stackoverflow 问题的答案中汲取灵感,我将 rspec 目录的不同组合运行在一起,以找出哪些可能会相互干扰。最后我发现我在打电话:

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

when I changed all occurrences of this to:

当我将所有出现的情况更改为:

before(:each) do
  :
end

All the specs passed without the failure:

所有规格都通过了,没有失败:

undefined method `authenticate' for nil:NilClass

I hope this is of help to others.

我希望这对其他人有帮助。

回答by Pete

If you're working with view spec, you can stub of current_user. This effectively overrides the current_userhelper called from your view with whatever is returned. Here's how with rspec-3.2.3:

如果您正在使用视图规范,则可以存根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

回答by Berin Loritsch

It looks like there are some updates to the source code. The ApplicationController specifies that there needs to be an authenticate_user!filter run before any request. This thread provides some background on issues with it:

看起来源代码有一些更新。ApplicationController 指定authenticate_user!在任何请求之前都需要运行过滤器。这个线程提供了一些关于它的问题的背景:

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

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

Essentially, the authenticate_user!function is part of Rails 3 (using the new devisefeature, of which I know little about). If the app can't find the User model (either because of namespace issues or whatever reason) then the method will fail. The "enki" application you linked to is now a Rails 3 application. It could be experiencing a few growing pains as it converts over.

从本质上讲,该authenticate_user!功能是 Rails 3 的一部分(使用新devise功能,我对此知之甚少)。如果应用程序找不到 User 模型(由于命名空间问题或任何原因),则该方法将失败。您链接到的“enki”应用程序现在是一个 Rails 3 应用程序。它在转换时可能会经历一些成长的痛苦。

回答by Boris Stitnicky

Ruby is telling you, that method #authenticatehas not been definded on nilyet. You can do it easily by:

红宝石在告诉你,这种方法#authenticate还没有被definded上nil呢。您可以通过以下方式轻松完成:

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

And the error will go away.

错误就会消失。