我有一个资源,其中新操作要求用户登录才能查看。如果用户尝试在未登录的情况下创建新资源,则会将其重定向(302' d)到登录页面。我的功能测试如下:
test "should not get new unless logged in" do
get :new
assert_response :redirect
end
stacktrace看起来像这样:
ArgumentError: uncaught throw :warden
/.../gems/warden-1.1.1/lib/warden/proxy.rb:114:in `throw'
/.../gems/ruby-1.9.2-p318/gems/warden-1.1.1/lib/warden/proxy.rb:114:in `authenticate!'
/.../gems/ruby-1.9.2-p318/gems/devise-2.0.4/lib/devise/controllers/helpers.rb:48:in `authenticate_user!'
在新操作之前,我有一个before_filter到authenticate_user。
我理解为什么authenticate_user!失败但我无法理解为什么它会抛出错误。不应该像在webapp中那样行事,即。将用户重定向到登录页面?
感谢。
答案 0 :(得分:4)
class ActionController::TestCase
include Devise::TestHelpers
end
特别是,不要将include Devise::TestHelpers
放入class
ActiveSupport::TestCase
。
答案 1 :(得分:2)
当Warden和/或Devise夹杂物缺失或没有添加到适当的位置时会发生这种情况。将它们添加到test_helper.rb中很有吸引力,因为那是助手通常会去的地方,但对于Devise来说无法正常工作。
有关详细信息,请参阅https://github.com/plataformatec/devise/issues/1029。
要解决此问题,请在控制器的测试类中包含Devise助手和Warden助手,如下所示:
require 'test_helper'
class UserControllerTest < ActionController::TestCase
include Devise::TestHelpers
include Warden::Test::Helpers
Warden.test_mode!
def teardown
Warden.test_reset!
end
# test "the truth" do
# assert true
# end
end
每个使用Devise身份验证的控制器都需要这样做。
编辑:
如下面的评论所述,将include Warden:TestHelpers
从spec_helper.rb(或test_helper.rb)移动到rails_helper.rb也可以。
答案 2 :(得分:1)
我收到了这个错误,但这是因为我将include Devise::TestHelpers
置于我的班级定义之外。
require 'test_helper'
include Devise::TestHelpers
class Admin::ObservationsControllerTest < ActionController::TestCase
setup do
...
这引起了我的7个测试用例中的3个的监护人错误。
在类定义中移动include
修复了所有内容。
答案 3 :(得分:0)
我知道这是一个老问题,但我找到了Devise wiki的答案
https://github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara
这是一个循序渐进的指南,在这里重新创建,但第一步是包括Warden测试助手
include Warden::Test::Helpers
Warden.test_mode!
希望这有帮助