Ruby on rails 轨道4+;设计:如何在没有RSpec的情况下编写设计重置密码的测试?
由于我无法控制的原因,我无法在当前项目中使用RSpec进行测试。我正在试着设计重置密码,但似乎找不到有效的方法 以下是我目前掌握的情况:Ruby on rails 轨道4+;设计:如何在没有RSpec的情况下编写设计重置密码的测试?,ruby-on-rails,ruby-on-rails-4,devise,minitest,Ruby On Rails,Ruby On Rails 4,Devise,Minitest,由于我无法控制的原因,我无法在当前项目中使用RSpec进行测试。我正在试着设计重置密码,但似乎找不到有效的方法 以下是我目前掌握的情况: require 'test_helper' class ResetPasswordTest < ActionDispatch::IntegrationTest setup do @user = users(:example) end test "reset user's password" do old_password
require 'test_helper'
class ResetPasswordTest < ActionDispatch::IntegrationTest
setup do
@user = users(:example)
end
test "reset user's password" do
old_password = @user.encrypted_password
puts @user.inspect
# This assertion works
assert_difference('ActionMailer::Base.deliveries.count', 1) do
post user_password_path, user: {email: @user.email}
end
# puts @user.reset_password_token => nil
# Not sure why this doesn't assign a reset password token to @user
patch "/users/password", user: {
reset_password_token: @user.reset_password_token,
password: "new-password",
password_confirmation: "new-password",
}
# I get a success here, but I'm not sure why, since reset password token is nil.
assert_response :success
# This assertion doesn't work.
assert_not_equal(@user.encrypted_password, old_password)
end
end
需要“测试助手”
类ResetPasswordTestnil
#不确定为什么这不会将重置密码令牌分配给@user
修补程序“/用户/密码”,用户:{
重置密码令牌:@user.reset密码令牌,
密码:“新密码”,
密码确认:“新密码”,
}
#我在这里获得了成功,但我不确定为什么,因为重置密码令牌为零。
断言:成功
#这个断言不起作用。
断言不等于(@user.encrypted\u password,old\u password)
结束
结束
我在上面添加了一些评论,这些评论似乎不起作用。有人对如何更好地测试这一点有见解或想法吗 我发现您需要在发送密码重置电子邮件时重新加载用户,并在
点击/user/password
路线时重新加载用户。您还需要从电子邮件中获取密码令牌,因为它与存储在数据库中的不同
require 'test_helper'
class ResetPasswordTest < ActionDispatch::IntegrationTest
setup do
@user = users(:example)
end
test "reset user's password" do
# store old encrypted password
old_password = @user.encrypted_password
# check to ensure mailer sends reset password email
assert_difference('ActionMailer::Base.deliveries.count', 1) do
post user_password_path, user: {email: @user.email}
assert_redirected_to new_user_session_path
end
# Get the email, and get the reset password token from it
message = ActionMailer::Base.deliveries[0].to_s
rpt_index = message.index("reset_password_token")+"reset_password_token".length+1
reset_password_token = message[rpt_index...message.index("\"", rpt_index)]
# reload the user and ensure user.reset_password_token is present
# NOTE: user.reset_password_token and the token pulled from the email
# are DIFFERENT
@user.reload
assert_not_nil @user.reset_password_token
# Ensure that a bad token won't reset the password
put "/users/password", user: {
reset_password_token: "bad reset token",
password: "new-password",
password_confirmation: "new-password",
}
assert_match "error", response.body
assert_equal @user.encrypted_password, old_password
# Valid password update
put "/users/password", user: {
reset_password_token: reset_password_token,
password: "new-password",
password_confirmation: "new-password",
}
# After password update, signed in and redirected to root path
assert_redirected_to root_path
# Reload user and ensure that the password is updated.
@user.reload
assert_not_equal(@user.encrypted_password, old_password)
end
end
需要“测试助手”
类ResetPasswordTest
designe在内部测试密码控制器
。我想用额外的功能测试我的密码控制器
,并前往寻求帮助,为designe的默认功能构建测试,然后将我的新功能的断言添加到测试用例中
如其他答案中所述,您必须获得重置密码\u令牌
。您可以通过与Desive相同的方式获得令牌,而不是像这里的另一个解决方案那样解析已发送的电子邮件:
setup do
request.env["devise.mapping"] = Devise.mappings[:user]
@user = users(:user_that_is_defined_in_fixture)
@reset_password_token = @user.send_reset_password_instructions
end
查看Desive针对密码控制器测试的解决方案
:
这段代码需要email_spec和FactoryGirl gems。您如何运行此测试?您将测试文件放在哪个目录下?@MinaZaki我将此测试放在/test/integration/
中,它只使用rake test
…或运行rake test:integration
@Bryan Ash感谢您的编辑!我忘记了答案可以排序!这应该是可接受的答案,因为直接获取令牌而不是电子邮件解析更好。真的很酷的方法!但是如果你使用水豚,电子邮件规范对你没有帮助。请改用
require 'rails_helper'
feature 'User' do
let(:user) { create(:user) }
let(:new_password) { 'Passw0rd!' }
it 'reset password' do
visit '/'
click_link 'Forgot password?'
fill_in 'E-mail', with: user.email
expect do
click_button 'Send me reset password instructions'
end.to change(ActionMailer::Base.deliveries, :count).by(1)
expect(unread_emails_for(user.email)).to be_present
open_email(user.email, with_subject: 'Reset password instructions')
click_first_link_in_email
fill_in 'New password', with: new_password
fill_in 'Confirm new password', with: new_password
click_button 'Change password'
expect(page).to have_notice 'Your password has changed'
click_link 'Logout'
fill_in 'E-mail', with: user.email
fill_in 'Password', with: new_password
click_button 'Sign in'
expect(page).to have_notice 'Wellcome!'
end
end