使用 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_password 应该这样定义:
encrypted_password: <%= Devise.bcrypt(User, 'password') %>
其中User
是您的用户模型的类。
请注意,这只适用于使用默认加密算法 (bcrypt) 的情况。
Devise 3.5.1 及更高版本的解决方案
正如Katarzyna 指出的那样:Device.bcrypt has been deprecated 在版本 3.5.1 中。从那个版本开始, encrypted_password 应该这样定义:
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