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
相关产品推荐
相关产品推荐

