Rails UsersController测试报错:用户计数未变与重定向异常修复
问题分析与修复方案
错误核心原因
三个测试错误的本质都是测试未做用户身份验证,但你的控制器里配置了登录权限校验(比如Devise的authenticate_user!回调),导致测试请求被直接拦截重定向,根本没执行预期的控制器动作。
1. test_should_destroy_user 计数未减少
- 原因:测试发起删除请求时,用户处于未登录状态,控制器的权限校验直接拦下请求,
destroy方法里的@user.destroy代码根本没执行,所以数据库用户数量没变化。
2. test_should_get_edit 返回302而非2XX
- 原因:访问
edit页面需要登录权限,未登录的测试请求被重定向到登录页,返回302状态码,自然不符合预期的成功响应。
3. test_should_update_user 跳转到登录页而非用户页
- 原因:更新用户的
update动作需要登录权限,未登录的测试请求被拦截重定向,根本走不到更新完成后跳转到用户详情页的逻辑。
修复方案
假设你用Devise做身份验证,在测试里添加登录逻辑就能解决所有问题:
步骤1:在测试文件中添加登录逻辑
修改test/controllers/users_controller_test.rb,提前创建测试用户并在测试前完成登录:
require "test_helper" class UsersControllerTest < ActionDispatch::IntegrationTest # 前置准备:创建测试用户并登录 setup do # 用fixtures里的测试用户,或者手动创建 @user = users(:one) # Devise的登录辅助方法,没有的话看步骤2 sign_in @user end test "should destroy user" do assert_difference('User.count', -1) do delete user_url(@user) end assert_redirected_to users_url end test "should get edit" do get edit_user_url(@user) assert_response :success end test "should update user" do patch user_url(@user), params: { user: { name: @user.name, email: "updated@example.com" } } assert_redirected_to user_url(@user) @user.reload assert_equal "updated@example.com", @user.email end end
步骤2:确保测试环境加载Devise辅助方法
如果sign_in方法报错,在test/test_helper.rb里添加:
class ActionDispatch::IntegrationTest include Devise::Test::IntegrationHelpers end
自定义权限校验的适配
如果你的权限校验是自己写的(不是用Devise),就在setup里手动模拟登录会话:
setup do @user = User.create(name: "测试用户", email: "test@example.com", password: "123456") # 把用户ID存入会话,模拟登录状态 session[:user_id] = @user.id end
验证修复
运行测试命令确认修复效果:
rails test test/controllers/users_controller_test.rb
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

