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

使用react-hook-form与zod构建的表单测试失败问题排查

问题解决:React Hook Form + Zod 表单校验测试不显示错误提示

问题原因

你的Zod校验规则存在核心问题:

  • z.string()默认允许空字符串,提交空密码时Zod不会判定为错误,因此不会渲染对应的alert提示
  • 邮箱字段的z.string().email()会拒绝空字符串(空串不符合邮箱格式),但密码字段无空值限制,导致测试期望的2个alert元素无法全部出现

修复步骤

1. 更新Zod校验Schema

修改表单校验规则,给两个字段添加nonempty()约束,确保空值被判定为无效:

import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import { z } from 'zod'

// 修改后的Schema,添加nonempty限制
const formSchema = z.object({
  email: z.string().nonempty('邮箱不能为空').email('请输入有效的邮箱地址'),
  password: z.string().nonempty('密码不能为空'),
})

type Input = z.infer<typeof formSchema>

export function SimpleForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<Input>({ resolver: zodResolver(formSchema) })

  function onSubmit() {}

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor='email'>email</label>
      <input id='email' {...register('email')} type='email' />
      {errors.email && <span role='alert'>{errors.email.message}</span>}
      <label htmlFor='password'>password</label>
      <input id='password' {...register('password')} type='password' />
      {errors.password && <span role='alert'>{errors.password.message}</span>}
      <button type='submit'>SUBMIT</button>
    </form>
  )
}

2. 测试代码无需修改

你的测试逻辑是正确的,修改Schema后,提交空表单时两个字段都会触发校验错误,渲染对应的alert元素,screen.findAllByRole('alert')会找到2个元素,测试即可通过。

补充说明

  • Zod的z.string()仅校验值类型为字符串,空字符串""属于合法字符串,不会触发错误
  • nonempty()方法强制要求字符串长度至少为1,是处理必填字段空值校验的标准方式
  • React Hook Form的handleSubmit会在提交时自动触发Zod resolver的校验,校验失败后更新formState.errors,从而渲染错误提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:00:28