You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails用户注册测试报错:RuntimeError与422错误解决咨询

问题与解决

错误说明

注册功能在应用中正常运行,但执行rails test时触发以下错误:

UsersSignupTest#test_invalid_signup_information: RuntimeError: not a redirect! 422 Unprocessable Entity
报错位置:test/integration/users_signup_test.rb:18:in `block in class:UsersSignupTest'

错误原因

问题出在invalid signup information测试用例的逻辑错误:

  • 提交无效注册数据时,后端会触发模型验证失败,此时UsersController的create动作应该重新渲染注册页面(users/new),而非重定向。
  • 但测试里调用了follow_redirect!方法,该方法仅在响应为3xx重定向状态码时才能正常执行,而验证失败返回的是422状态码,因此直接抛出"not a redirect!"错误。
  • 测试中还错误断言会跳转到users/show页面且用户已登录,这完全不符合无效注册的预期——无效数据不会创建用户,更不会自动登录。

修复步骤

修改test/integration/users_signup_test.rb中的invalid signup information测试用例,调整逻辑匹配无效注册的实际行为:

require "test_helper"

class UsersSignupTest < ActionDispatch::IntegrationTest
  test "invalid signup information" do
    get signup_path
    assert_no_difference 'User.count' do
      post users_path, params: { user: { 
        name: "",
        email: "user@invalid",
        password: "foo",
        password_confirmation: "bar" 
      } }
    end
    # 移除错误的follow_redirect!,此时无重定向操作
    assert_template 'users/new' # 断言停留在注册页面
    assert_not is_logged_in? # 断言用户未登录
    # 可选:如果视图有错误提示逻辑,可添加以下断言
    # assert_select 'div#error_explanation'
    # assert_select 'div.field_with_errors'
  end

  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { 
        name: "Example User",
        email: "user@example.com",
        password: "password",
        password_confirmation: "password" 
      } }
    end
    follow_redirect!
    assert_template 'users/show'
    assert is_logged_in?
  end
end

补充说明

  • 422 Unprocessable Entity状态码表示服务器理解请求内容,但无法处理其中的验证错误,这是Rails处理表单验证失败的标准响应。
  • 确保UsersController的create动作逻辑正确,验证失败时渲染注册页面:
# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      log_in @user # 若注册后自动登录则保留此句
      redirect_to @user
    else
      render :new, status: :unprocessable_entity
    end
  end

  # 其他动作...

  private
    def user_params
      params.require(:user).permit(:name, :email, :password, :password_confirmation)
    end
end

内容的提问来源于stack exchange,提问作者JS3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:12:32