我在迈克尔·哈特尔的教程中理解一个代码时遇到了问题。
在PasswordResetsTest
课程中,在测试password resets
中,我们将用户从灯具中取出,我们使用正确的邮件发布到password_resets_path
,我们声称@user.reset_digest
没有等于@user.reload.reset_digest
。
后来,Michael说我们需要使用assigns方法来修补password_reset_path
。他说这是因为我们来自灯具的用户没有reset_token
,因为它只在create_reset_digest方法中创建。
我明白了,但我没有得到一件事 - 为什么assert_not_equal
在重新加载用户reset_digest
之前和之后通过了?{
我认为它是这样的:reset_digest
首先是nil
,我们发布到password_resets_path
,这是PasswordResetsController
的创建动作;在此操作中,我们有create_reset_digest
方法。 reset_digest
已经不再存在,我们重新加载它并且我们的assert_not_equal传递。
但如果是这样,那么来自灯具的@user
现在也应该reset_token
(如果其reset_digest
受到创建操作(特别是create_reset_digest
方法)的影响。
有人可以看看吗? :)
require 'test_helper'
class PasswordResetsTest < ActionDispatch::IntegrationTest
def setup
ActionMailer::Base.deliveries.clear
@user = users(:michael)
end
test "password resets" do
get new_password_reset_path
assert_template 'password_resets/new'
# Invalid email
post password_resets_path, password_reset: { email: "" }
assert_not flash.empty?
assert_template 'password_resets/new'
# Valid email
post password_resets_path, password_reset: { email: @user.email }
assert_not_equal @user.reset_digest, @user.reload.reset_digest
assert_equal 1, ActionMailer::Base.deliveries.size
assert_not flash.empty?
assert_redirected_to root_url
# Password reset form
user = assigns(:user)
# Valid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: {
password: "foobaz",
password_confirmation: "foobaz"
}
end
end
def create_reset_digest
self.reset_token = User.new_token
#creating reset_digest
end
def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
if @user
@user.create_reset_digest
# ...
end
end
答案 0 :(得分:0)
我问了一位来源 - 这本书的作者迈克尔哈特尔:)
他的回答:&#34;自从我查看该代码以来已经有一段时间了,但我认为发生了什么@user
有一个reset_digest
但是不是reset_token
。 post
密码重置路径会更改@user
方法中的create
变量,但该变量与测试中的变量不同。这就是为什么有必要调用assigns
的原因:测试中的@user
没有虚拟reset_token
属性,但控制器中的属性有。{&1}}。 #34;
老实说,我仍然没有得到它 - 为什么reset_digest测试变量&#34; @ user&#34;变化,如果它不是受创造行动影响的变量?