2

在我的(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

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

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

编辑:

我验证了我的设置在调用#authenticate 之前正在运行,并且Devise 确实在用一个Warden::Proxy对象初始化request.env['warden'],但是当调用#authenticate 时,`request.env['warden'] 为零。这是否意味着机架在单独的线程中运行或其他东西。如此混乱,我确定我做错了什么。-_-

4

1 回答 1

1

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

这是 routes.rb 中身份验证的优点和野兽:我们不必担心控制器级别的身份验证,但我们也不能在控制器级别测试我们的路由。至少目前不是(在 Rails 3.2 中),因为它是 Rails 的限制。

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

于 2012-03-14T13:43:46.530 回答