Rails测试报错:User.count未按预期减少-1,应用功能正常
问题分析与解决
错误信息
"User.count" 未按预期减少-1。预期值:1 实际值:2
实际操作删除功能正常,但测试时出现上述错误,核心原因是测试中登录的用户并非管理员,导致删除动作被前置过滤器拦截,具体分析和解决如下:
1. 登录逻辑的错误传递
你的测试代码中尝试通过session参数传递admin: true来登录管理员:
post login_path, params: { session: { email: "example@railstutorial.org", password: 'foobar', admin: true } }
但登录逻辑是基于数据库中用户的admin字段状态,而非登录请求里的参数。这个admin: true参数不会改变用户的实际权限,若你fixture(test/fixtures/users.yml)中example@railstutorial.org对应的用户没有设置admin: true,登录后current_user.admin?会返回false,触发admin_user前置过滤器的重定向,destroy方法里的删除逻辑根本没执行。
解决方法
直接使用fixture中已定义的管理员用户进行登录:
# 假设你的fixtures里有一个admin用户 admin_user = users(:admin) post login_path, params: { session: { email: admin_user.email, password: 'foobar' } }
或者检查users.yml,确保example@railstutorial.org用户的配置包含admin: true:
# test/fixtures/users.yml example: name: Example User email: example@railstutorial.org password_digest: <%= User.digest('foobar') %> admin: true # 加上这一行
2. 验证前置过滤器执行
确认UsersController中的前置过滤器顺序正确,admin_user在logged_in_user之后,确保先验证登录状态再检查管理员权限:
before_action :logged_in_user, only: [:index,:edit, :update, :destroy] before_action :correct_user, only: [:edit, :update] before_action :admin_user, only: :destroy
当前顺序是正确的,无需调整。
3. 确认测试用户存在
确保users(:manon)是fixtures中已定义的有效用户,避免因用户不存在导致删除动作无效果。
额外小问题(非当前错误原因)
会话助手的log_out方法最后一行遗漏了重置@current_user为nil,建议修正:
def log_out forget(current_user) session.delete(:user_id) @current_user = nil # 补充这一行 end
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

