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

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

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

  1. 已登录
  2. 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

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

【问题讨论】:

    标签: ruby-on-rails devise functional-testing fixtures


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-17
        • 2017-05-18
        • 2011-08-02
        相关资源
        最近更新 更多