使用 Rails 和 Devise 进行功能测试。在我的固定装置里放啥?

Posted

技术标签:

【中文标题】使用 Rails 和 Devise 进行功能测试。在我的固定装置里放啥?【英文标题】:Functional testing with Rails and Devise. What to put in my fixtures?使用 Rails 和 Devise 进行功能测试。在我的固定装置里放什么? 【发布时间】:2011-06-02 10:34:27 【问题描述】:

您好,我想对使用 Devise 和 CanCan 的 Rails 3 应用程序进行一些功能测试。

在我的用户模型中,我有用户年龄,我想测试用户是否只能访问某个页面:

    已登录 35岁以上

我在 Devise 文档中看到我可以使用:*sign_in* 并且我已将它放入我的测试中并且它似乎可以工作 - 测试没有出错,因为我有:

include Devise::TestHelpers

在我的 *test_helper.rb* 中

当我把它拿出来时,我的测试会出错,因为 *sign_in* 没有定义。所以这不是辅助问题。

当我运行测试并检查 span#loggedin 是否出现 1 次时,测试失败,因为出现 0 次。 span#loggedin 仅出现 *if user_signed_in?*

我需要在我的固定装置或测试中添加什么来创建一个测试用户,该用户也是一个完全注册的用户(确认等)?

查看代码:

<% if user_signed_in? %>
     <span id="loggedin">User is signed in</span>
     User age is <span id="age"><%= current_user.age.to_s %></span>
<% end %>

测试代码:

test "should get index" do
    sign_in :one
    get :index
    assert_response :success
    assert_select 'span#loggedin', :count => 1
end

夹具:

one:
 email: jez@example.com
 age: 36

当我手动登录时它在开发中工作正常,但我希望将这一切自动化 - 真正的测试点!!

【问题讨论】:

【参考方案1】:

Devise pre 3.2.0 解决方案

我认为这可能是您正在寻找的:

User.new.send(:password_digest, 'password')

salt 为 nil 时有效。

因此,在您的夹具中,您可以这样做:

one:
  email: 'some@user.com'
  encrypted_password: <%= User.new.send(:password_digest, 'password') %>

设计版本 3.2.0 到 3.5.0 的解决方案

在设计 3.2.0 中,method was created precisely for this purpose(@Inkling 更新)。对于这些版本, encrypted_pa​​ssword 应该这样定义:

encrypted_password: <%= Devise.bcrypt(User, 'password') %>

其中User 是您的用户模型的类。

请注意,这只适用于使用默认加密算法 (bcrypt) 的情况。


Devise 3.5.1 及更高版本的解决方案

正如Katarzyna 指出的那样:Device.bcrypt has been deprecated 在版本 3.5.1 中。从那个版本开始, encrypted_pa​​ssword 应该这样定义:

encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>

【讨论】:

如果您不熟悉应用程序并且不确定 Devise 使用的是什么加密算法,请检查 config/initializers/devise.rb 文件中的 config.encryptor 设置。另一个线索是 Gemfile 是否包含 gem 'devise-encryptable'(用于选择 bcrypt 以外的任何内容进行加密)。 Devise.bcrypt 已弃用;使用 Devise::Encryptor.digest 我在使用上面的代码时得到一个未初始化的常量 Devise::Encryptor.. 有什么想法吗? @BrianDear 您使用的是 3.5.1 之前的版本吗?如果是这样,您应该尝试其他选项之一(3.2 到 3.5:bcrypt,3.2 之前的:password_digest)或更新您的 Devise 版本。 谢谢!这在 2019 年 2 月仍然有效【参考方案2】:

我已经解决了问题 - 我错误地登录了用户。

我的测试应该是:

test "should get index" do
    @user = users(:one)
    sign_in @user
    get :index
    assert_response :success
    assert_select 'span#loggedin', :count => 1
 end

这也有效,省去了一行代码:

test "should get index" do
    sign_in users(:one)
    get :index
    assert_response :success
    assert_select 'span#loggedin', :count => 1
end

我对 Fixtures 的理解不够……

但回到问题 - 在固定装置中放置什么:

one:
 email: jez@example.com
 encrypted_password: $2a$10$PoBe1MvkoGJsjMVTEjKqgeBUp.xdfzWoiDjBzQhtLAj16NqIa2fOy
 password_salt: $2a$10$PoBe1MvkoGJsjMVTEjKqge
 reset_password_token: nil
 remember_token: nil
 remember_created_at: nil
 sign_in_count: 1
 current_sign_in_at: 2011-01-02 08:31:23
 last_sign_in_at: 2011-01-02 08:31:23
 current_sign_in_ip: 127.0.0.1
 last_sign_in_ip: 127.0.0.1
 confirmation_token: nil
 confirmed_at: 2011-01-02 08:31:23
 confirmation_sent_at: 2011-01-02 08:30:59
 failed_attempts: 0
 unlock_token: nil
 locked_at: nil
 authentication_token: nil
 created_at: 2011-01-02 08:30:59
 updated_at: 2011-01-02 08:31:23
 age: 36

现在可以了。如果在开发中生成用户并将数据粘贴到夹具中更容易,请发布。

【讨论】:

您可以在您的灯具中使用 ERB,这将帮助您使灯具更易于维护。您可以使用 FactoryGirl 之类的工具来代替(或结合使用)fixture,这将使您的测试更易于维护,但会显着减慢您的测试速度。 我知道在我的灯具中使用 ERB,但是我需要什么 ERB 来生成上面的灯具?这就是我的问题的核心——特别是我需要在我的固定装置中放什么? 我知道这是一个老歌,但我偶然发现它在类似情况下寻求帮助。我的实验表明,只需在您的夹具中添加一个confirmed_at 时间戳似乎就可以解决问题。【参考方案3】:

还有一个提示。这对我很有用:

http://brandonhilkert.com/blog/managing-login-passwords-for-capybara-with-minitest-and-rails-fixtures/

而且它似乎是干燥且不错的解决方案。

【讨论】:

【参考方案4】:

它对我有用。

我没有改变我的用户夹具上的任何东西,就像这样:

one:
  id: 1
  name: MyString
  email: mystring@test.com
  group_id: 2
  encrypted_password: <%= Devise.bcrypt(User, 'password') %>

但我更改了我的 test_helper.rb 并将其添加到 ActionController 类中(这将适用于所有控制器测试):

class ActionController::TestCase
    include Devise::TestHelpers

    setup do
        sign_in users(:one)
    end
end

【讨论】:

以上是关于使用 Rails 和 Devise 进行功能测试。在我的固定装置里放啥?的主要内容,如果未能解决你的问题,请参考以下文章

向 iOS 应用程序公开 Rails/Devise 身份验证

Heroku上的现有Ruby on Rails Web应用程序(PostgreSQL),Devise身份验证,需要为移动支持添加Rails API

如何从 Rails 控制台使用 Devise 登录用户?

这个 Rails JSON 身份验证 API(使用 Devise)安全吗?

Devise for Rails中的唯一用户名

Rails 3 using Devise:如何允许某人使用他们的 Facebook 帐户登录?