我的大多数测试都提出了以下内容,我不明白为什么。所有方法调用都会引发“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如果你想自己运行测试。
答案 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)
正如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
错误将消失。