我的问题不是测试失败;所有测试都通过,直到现在。 代码示例在Michael Hartl的书中(您可能已经猜到了)。 我看看这个测试:
test "current_user returns nil when remember digest is wrong" do
@user.update_attribute(:remember_digest, User.digest(User.new_token))
assert_nil current_user
end
我的问题很简单:请解释一下,为什么remember_digest
错在这里?什么可以让它错?
有关详细信息,该文件为test/helpers/sessions_helper_test.rb
,并以此方法开头:
def setup
@user = users(:michael)
remember(@user)
end
users(:michael)
在文件test/fixtures/users.yml
答案 0 :(得分:1)
你做对了 - 当current_user
错误时,此测试确保nil
为remember_digest
,这意味着如果Cookie与预期不同,则用户未登录
请注意,我们添加了第二个测试,用于检查当前测试 如果用户的记忆摘要不正确对应,则user为nil 记住令牌,从而测试经过验证的?表达 在嵌套的if语句中:
if user && user.authenticated?(cookies[:remember_token])
setup
在测试之前运行:
def setup
@user = users(:michael)
remember(@user)
end
并且remember
功能通过在Cookie中设置remember_digest
来设置用户remember_token
:
# Remembers a user in a persistent session.
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
然后,测试会将用户的remember_digest
替换为随机值的摘要,从而使Cookie无效:
@user.update_attribute(:remember_digest, User.digest(User.new_token))
所以current_user
是nil
,这意味着没有用户登录。
答案 1 :(得分:0)
看看:
def current_user
if (user_id = session[:user_id]) # i.e., if the user is logged in (has a session w/ user's id)
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(cookies[:remember_token])
log_in user
@current_user = user
end
end
end
(来自sessions_helper.rb) - 具体来说,请看语句:
if user && user.authenticated?(cookies[:remember_token])
请注意,如果user.authenticated?(cookies[:remember_token])
失败,则不会分配实例变量@current_user
。在这种情况下,@current_user
的值将为零。
要获得更好的主意,请在rails控制台中尝试:
>> user = User.create(name: "Michael", email: "example@michael.com", password: "foobar", password_confirmation: "foobar")
>> user.remember_token
=> nil
>> user.remember
>> user.remember_token
=> "68ObMQCCdjURdwH0QVEL7w"
>> token = user.remember_token
>> user.authenticated?(token)
=> true
>> user.update_attribute(:remember_digest, User.digest(User.new_token))
>> user.authenticated?(token)
=> false
制作最后一行=> true
:
>> user.remember
>> new_token = user.remember_token
>> user.authenticated?(new_token)
=> true
现在回顾一下session_helper_test.rb,因为在设置中调用remember
方法,而不是在测试块中调用@user.update_attribute(:remember_digest, User.digest(User.new_token))
之后,我们可以预期user.authenticated?(user.remember_token)
会失败。因此,语句if user && user.authenticated?(cookies[:remember_token])
将为false
。因此,@current_user
永远不会给出值,因此会nil
。