在我的 (Rails 3.2) Test::Unit 控制器/功能测试中,assert_routing 失败并出现以下错误:

  1) Error:
test: with an admin user routing should route GET /admin/contracts to/from {:action=>"index", :controller=>"admin/contracts"}. (Admin::ContractsControllerTest):
NoMethodError: undefined method `authenticate!' for nil:NilClass

与路线:

authenticate :admin do
  namespace :admin do
    resources :contracts
  end
end

我正在控制器测试中设置 Devise 2.0 身份验证:

admin = Factory.create(:admin)
admin.confirm!
@request.env["devise.mapping"] = Devise.mappings[:admin]
sign_in :admin, admin

这个答案 对 Warden 进行控制器测试 表明即使在我的应用程序运行之前,机架也可能正在进行身份验证。这很奇怪,因为我的控制器测试正在运行并且应该已经设置了 env 变量。但在调用验证时, request.env["warden"] 为零。

是这样吗,在 Devise 助手设置环境变量之前,该机架正在运行?如果是这样,在机架检查我的路由文件之前如何设置身份验证?我的其他断言通过了,但assert_routing似乎是一个特例。

编辑:

我验证了我的设置在调用 #authenticate 之前正在运行,并且 Devise 确实使用 a 初始化 request.env['warden'] Warden::Proxy 对象,但是当调用 #authenticate 时,`request.env['warden'] 为零。这是否意味着机架正在单独的线程或其他线程中运行。太令人困惑了,我确信我做错了什么。-_-

有帮助吗?

解决方案

控制器(功能)测试应该保留在控制器级别,并且无权访问较低级别的环境状态。所以 request.env['warden'] 在 Devise::TestHelper 中进行模拟,以便控制器级别测试可以通过,但是当 Rack 运行时 request.env 哈希为 nil 并且路由失败并出现上述错误。

这就是在routes.rb中进行身份验证的美妙之处和野兽之处:我们不必担心控制器级别的身份验证,但我们也无法在控制器级别测试路由。至少目前(在 Rails 3.2 中)不是这样,因为这是 Rails 的限制。

请参阅已关闭的问题 https://github.com/plataformatec/devise/issues/1670

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top