使用 devise 进行 RSpec 测试:找不到有效的映射

发布于 2024-11-06 16:45:50 字数 1692 浏览 3 评论 0原文

我正在尝试使用 devise 1.3.4 运行控制器规范。 (还有工厂女工) 我按照 git wiki 中的项目说明进行操作。我可以使用在宏中创建的 login_user 方法以用户身份登录,但 login_admin 失败并出现以下错误:

...
sign_in Factory.create(:admin)

Could not find a valid mapping for #<User id: 2023, email: "[email protected]", .... >

Factory:

Factory.define :user do |f|
  f.sequence(:username) {|n| "user#{n}"}
  f.sequence(:email) {|n| "user#{n}@gmail.com"}
  f.email_confirmation {|fac| fac.email }
  f.password "a12345Den123"
  f.password_confirmation "a12345Den123"
#  f.admin 0
end

Factory.define :admin, :class => User do |f|
  f.sequence(:username) {|n| "admin#{n}"}
  f.sequence(:email) {|n| "admin#{n}@gmail.com"}
  f.email_confirmation {|fac| fac.email }
  f.password "a12345Den123"
  f.password_confirmation "a12345Den123"
  f.admin 1
end

Controller macros module:

module ControllerMacros
  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]  #it should map to user because admin is not a model of its own.  It produces the same result either way.
      @admin = Factory.create(:admin)
      sign_in @admin
    end
  end

  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      sign_in @user
    end
  end
end

paths

devise_for :users
devise_for :admins, :class_name => 'User'

一种解决方案是设置 cache_classes = false,但这并不理想,因为我使用 spork 并且不想在更改模型后重新启动它。

有什么帮助吗?

I'm trying to run controller specs with devise 1.3.4. (and factory girl)
I followed the instructions in the git wiki for the project. I am able to log in as a user using the login_user method created in the macro, but login_admin fails with the following error:

...
sign_in Factory.create(:admin)

Could not find a valid mapping for #<User id: 2023, email: "[email protected]", .... >

Factory:

Factory.define :user do |f|
  f.sequence(:username) {|n| "user#{n}"}
  f.sequence(:email) {|n| "user#{n}@gmail.com"}
  f.email_confirmation {|fac| fac.email }
  f.password "a12345Den123"
  f.password_confirmation "a12345Den123"
#  f.admin 0
end

Factory.define :admin, :class => User do |f|
  f.sequence(:username) {|n| "admin#{n}"}
  f.sequence(:email) {|n| "admin#{n}@gmail.com"}
  f.email_confirmation {|fac| fac.email }
  f.password "a12345Den123"
  f.password_confirmation "a12345Den123"
  f.admin 1
end

Controller macros module:

module ControllerMacros
  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]  #it should map to user because admin is not a model of its own.  It produces the same result either way.
      @admin = Factory.create(:admin)
      sign_in @admin
    end
  end

  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      sign_in @user
    end
  end
end

routes

devise_for :users
devise_for :admins, :class_name => 'User'

One solution is to set cache_classes = false, however that isn't ideal as I use spork and don't want to have to restart it after changing a model.

Any help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉酒的小男人 2024-11-13 16:45:50

我的路线中有这样的东西:

  devise_for :accounts, :controllers => {:confirmations => "confirmations"} do
    put "confirm_account", :to => "confirmations#confirm_account"
    get "login" => "devise/sessions#new", :as => :login
    delete "logout" => "devise/sessions#destroy", :as => :logout
    get "register" => "devise/registrations#new", :as => :register
  end

所以在我的spec/support/controller_macros.rb中我需要更改:

  def login_account
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:account]
      @account = Factory.create(:account)
      sign_in(@account)
    end
  end

  def login_account
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:account]
      @account = Factory.create(:account)
      sign_in(:account, @account)
    end
  end

记下sign_in(范围,资源)

我希望这会有所帮助。

I have something like this in my routes:

  devise_for :accounts, :controllers => {:confirmations => "confirmations"} do
    put "confirm_account", :to => "confirmations#confirm_account"
    get "login" => "devise/sessions#new", :as => :login
    delete "logout" => "devise/sessions#destroy", :as => :logout
    get "register" => "devise/registrations#new", :as => :register
  end

so in my spec/support/controller_macros.rb I needed to change from:

  def login_account
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:account]
      @account = Factory.create(:account)
      sign_in(@account)
    end
  end

to

  def login_account
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:account]
      @account = Factory.create(:account)
      sign_in(:account, @account)
    end
  end

note the sign_in(scope, resource)

I hope this helps.

三生一梦 2024-11-13 16:45:50

这是来自设备自述文件:

Devise 还附带默认路由。
如果您需要自定义它们,您
应该可以做到
通过 devise_for 方法。它
接受几个选项,例如
:class_name, :path_prefix 等等,
包括改变的可能性
I18n 的路径名

所以我会检查你的路由文件并确保它在其中:

devise_for :admins, :class_name => 'User'

This is from the devise readme:

Devise also ships with default routes.
If you need to customize them, you
should probably be able to do it
through the devise_for method. It
accepts several options like
:class_name, :path_prefix and so on,
including the possibility to change
path names for I18n

So I would check your routes file and make sure this is in there:

devise_for :admins, :class_name => 'User'
七堇年 2024-11-13 16:45:50

您可能需要检查代码中不同位置的多个 devise_for :admins 声明。这就是我的案例中出现这种异常的原因,因为它肯定会让 Devise 感到困惑。

You may want to check your code for multiple devise_for :admins declarations in different places. This has been the cause of such an exception in my case, as it surely confuses Devise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文