所有 Ruby 测试引发: nil 的未定义方法‘ enticate’: NilClass

我的大多数测试都提出了以下问题,我不明白为什么。所有方法调用都会引发“ Authate”错误。我已经检查了代码,如果有一个方法称为“认证”,但没有这样的方法。

  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

39690 次浏览

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

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

从本质上讲,authenticate_user!函数是 Rails3的一部分(使用新的 devise特性,对此我知之甚少)。如果应用程序无法找到 User 模型(不管是由于名称空间问题还是其他原因) ,那么该方法将失败。您链接到的“ enki”应用程序现在是一个 Rails 3应用程序。它可能正在经历一些成长的痛苦,因为它转换成。

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

@ jeffehh 你需要创建一个 Spec/support/devise.rb 文件作为 在此指明 https://github.com/plataformatec/devise#test-helpers至 包括设计测试助手 # 红宝石

再次感谢。

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

class ActiveSupport::TestCase
include Devise::TestHelpers
end

Ruby 告诉你,这个方法 #authenticate还没有在 nil上定义,你可以通过以下方法轻松实现:

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

错误就会消失。

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

请参阅 https://stackoverflow.com/a/21166482/1161743以获得对我有效的解决方案。

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

before :each do
sign_out :user
end

在 RSpec

正如杰弗里 W 提到的,在他的 上面的回答-> 设置为所有控制器:

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

然而,如果这只与一个规范有关,你不一定需要包括所有控制器规范的设计帮助器,你可以只是明确地包括那些帮助器在一个控制器描述块:

require 'spec_helper'
describe MyCoolController
include Devise::TestHelpers


it { }
end

如果使用 view spec,则可以使用 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

在我的一个项目中,我也经历过同样的失败。 它使用 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

我希望这对别人有帮助。