Rails 7 记住登录功能测试接连失败求助
Rails 7 记住登录功能测试失败问题
测试用例代码
require 'test_helper' class SessionsHelperTest < ActionView::TestCase def setup @user = users(:tony) remember(@user) end test 'current user returns right user when session is nil' do assert_equal @user,current_user assert is_logged_in? end 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 end
SessionsHelper 中的 current_user 方法
def current_user if (user_id = session[:user_id]) @current_user ||= User.find_by(id: user_id) elsif (user_id = cookies.encrypted[: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
测试失败情况
保留认证判断时,第一个测试用例失败
FAIL SessionsHelperTest#test_current_user_returns_right_user_when_session_is_nil (0.10s) --- expected +++ actual @@ -1 +1 @@ -#<User id: 339078012, name: "tony fusco", email: "tony@example.com", created_at: "2022-10-04 07:33:09.980286000 +0000", updated_at: "2022-10-04 07:33:09.980286000 +0000", password_digest: [FILTERED], remember_digest: nil> +nil test/helpers/sessions_helper_test.rb:10:in `block in <class:SessionsHelperTest>'
注释认证判断时,第二个测试用例失败
FAIL SessionsHelperTest#test_current_user_returns_nil_when_remember_digest_is_wrong (2.29s) Expected #<User id: 339078012, name: "tony fusco", email: "tony@example.com", created_at: "2022-10-04 08:42:46.512404000 +0000", updated_at: "2022-10-04 08:42:48.782076000 +0000", password_digest: [FILTERED], remember_digest: "$2a$04$Haqx77Y7NRV/fCcirQiEU.tZnuqqXGIxD0n81FKTy84..."> to be nil. test/helpers/sessions_helper_test.rb:16:in `block in <class:SessionsHelperTest>'
解决思路与修复代码
1. 修正测试用例的session状态
第一个测试要求session为nil,但默认remember方法可能触发log_in设置了session值,需手动清除:
test 'current user returns right user when session is nil' do session[:user_id] = nil # 新增该行,确保走cookie验证分支 assert_equal @user, current_user assert is_logged_in? end
2. 确保User模型方法正确实现
检查remember和authenticated?方法,确保token与digest的生成、验证逻辑匹配:
class User < ApplicationRecord # 生成随机token def self.new_token SecureRandom.urlsafe_base64 end # 加密字符串 def self.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) end # 生成remember_token并保存加密后的digest def remember self.remember_token = User.new_token update_attribute(:remember_digest, User.digest(remember_token)) end # 验证token与digest是否匹配 def authenticated?(remember_token) return false if remember_digest.nil? BCrypt::Password.new(remember_digest).is_password?(remember_token) end end
3. 确认remember助手方法逻辑
确保remember方法正确设置cookie:
def remember(user) user.remember cookies.permanent.encrypted[:user_id] = user.id cookies.permanent[:remember_token] = user.remember_token end
内容的提问来源于stack exchange,提问作者tony
相关产品推荐
相关产品推荐

