我的大多数测试都提出了以下问题,我不明白为什么。所有方法调用都会引发“身份验证”错误。我检查了代码是否有一个名为“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)>'
该项目可以在那里找到=> https://github.com/agilepandas/enki 如果您想自己运行测试。
@MatthewClosson 在 Twitter 上回答了这个问题
@jeffehh 您需要创建一个 spec/support/devise.rb 文件,如此处指定的 https://github.com/plataformatec/devise#test-helpers 以包含设计测试助手#ruby
再次感谢。
我知道您正在使用 Rspec,但您可能会在使用 Test::Unit
时遇到同样的问题。您只需将设计测试助手添加到 test/test_helper.rb
class ActiveSupport::TestCase
include Devise::TestHelpers
end
在 RSpec
正如 Jeffrey W. 在他的 answer above ->将此设置为所有控制器:
RSpec.configure do |config|
# ...
config.include Devise::TestHelpers, type: :controller
# ...
end
但是,如果这仅与一个规范相关,则您不一定需要在所有控制器规范中包含设计助手,您可以在该控制器描述块中明确包含这些助手:
require 'spec_helper'
describe MyCoolController
include Devise::TestHelpers
it { }
end
上面的答案对我不起作用(RSpec 3.1)
有关对我有用的解决方案,请参阅 https://stackoverflow.com/a/21166482/1161743。
在设置变量之前,您需要注销匿名用户:
before :each do
sign_out :user
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
从this stackoverflow 问题的答案中获得灵感,我将不同的 rspec 目录组合运行在一起,以找出哪些目录可能相互干扰。最后我发现我在打电话:
before() do #note no :each passed to before
:
end
当我将所有出现的这种情况更改为:
before(:each) do
:
end
所有规格都通过了,没有失败:
undefined method `authenticate' for nil:NilClass
我希望这对其他人有帮助。
如果您使用视图规范,则可以存根 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
看起来源代码有一些更新。 ApplicationController 指定需要在任何请求之前运行 authenticate_user!
过滤器。这个线程提供了一些关于它的问题的背景:
http://groups.google.com/group/plataformatec-devise/browse_thread/thread/f7260ebe2d9f7316?fwc=1
本质上,authenticate_user!
功能是 Rails 3 的一部分(使用新的 devise
功能,我对此知之甚少)。如果应用程序找不到用户模型(由于命名空间问题或其他原因),则该方法将失败。您链接到的“enki”应用程序现在是 Rails 3 应用程序。当它转换过来时,它可能会经历一些成长的痛苦。
Ruby 告诉您,方法 #authenticate
尚未在 nil
上定义。您可以通过以下方式轻松完成:
def nil.authenticate!
puts "Bingo! Nil is now authentic!"
end
并且错误会消失。
不定期副业成功案例分享