所有Ruby测试都提出了:nil的未定义方法`authenticate':NilClass

时间:2010-11-29 21:05:29

标签: ruby-on-rails ruby testing rspec devise

我的大多数测试都提出了以下内容,我不明白为什么。所有方法调用都会引发“authenticate”错误。我已经检查了代码是否有一个名为“authenticate”的方法,但是没有这样的方法。

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

项目可以在那里找到=&gt; https://github.com/agilepandas/enki如果你想自己运行测试。

8 个答案:

答案 0 :(得分:190)

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

  

@jeffehh你需要创建一个   spec / support / devise.rb文件为   在这里指定https://github.com/plataformatec/devise#test-helpers来   包括设计测试助手#ruby

再次感谢。

答案 1 :(得分:72)

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

class ActiveSupport::TestCase
  include Devise::TestHelpers
end

答案 2 :(得分:7)

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

请参阅https://stackoverflow.com/a/21166482/1161743了解适合我的解决方案。

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

before :each do
  sign_out :user
end

答案 3 :(得分:7)

RSpec中的

正如Jeffrey W.在answer above - &gt;中提到的那样。将其设置为所有控制器:

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

但是,如果这只与一个规范相关,那么您不一定需要在所有控制器规范中包含设计帮助器,您只需在那个控制器描述块中明确包含这些帮助器:

require 'spec_helper'
describe MyCoolController
  include Devise::TestHelpers

  it { } 
end

答案 4 :(得分:1)

我在其中一个项目中遇到了同样的失败。 它使用Ruby 2.0.0-p598,Rails 3.2.21,RSpec 2.99。 当我一起运行所有规格时,问题就出现了。 当我单独运行规格时,它们通过了。 我的spec / spec_helper.rb中包含以下内容:

@using (Ajax.BeginForm("MyControllerAction",
    routeValues: null,
    ajaxOptions: new AjaxOptions
    {
        InsertionMode = InsertionMode.Replace,
        HttpMethod     = "POST",
        UpdateTargetId = "myDiv",
        OnSuccess = "refresh()",
        OnBegin = "showProgressBar()",
        OnFailure = "hideProgressBar()",
    },
    htmlAttributes: new
    {
        id     = "myForm"
    }
))

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

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

也没有:

before :each do
  sign_out :user
end

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

after :each do
  sign_out :user
end

当我将所有出现的内容更改为:

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

所有规格都没有失败:

before(:each) do
  :
end

我希望这对别人有帮助。

答案 5 :(得分: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

答案 6 :(得分:-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应用程序。它转换过来可能会经历一些成长的痛苦。

答案 7 :(得分:-19)

Ruby告诉你,尚未在#authenticate上定义nil方法。您可以通过以下方式轻松完成:

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

错误将消失。