如何用Jest测试Formik+Yup表单验证?验证失败问题求助
问题:Formik+Yup表单验证测试无法捕获错误提示
我最近在测试Formik+Yup表单验证时卡壳了——不管怎么调整测试逻辑,都没法让测试用例正确识别到表单提交后的错误提示。我写的测试代码如下:
it('displays error on submit if name is empty', async () => { const wrapper = mount(<MyFormik/>) const getForm = () => wrapper.find('form') wrapper.find('input[name="name"]').simulate('change', { persist: () => {}, target: { name: 'name', value: '' } }) wrapper.find('MyInnerForm').props().submitForm() await wait(0) // 试过等待下一个事件循环甚至1秒... wrapper.update() expect( wrapper.update().find('.error').exists() ).toBeTruthy() // 结果一直是FALSE! })
不管我在提交后怎么等待、更新wrapper,Formik的errors属性始终是空对象。我查看了提交后的Formik props日志:
{ errors: {}, label: '', name: 'name', type: 'text', values: { name: '' }, touched: { name: true }, isValidating: false, status: undefined, initialValues: { name: '' }, validateOnChange: true, validateOnBlur: true } ... submitCount: 1, isValid: false
明明submitCount是1,isValid是false,但就是没有错误信息输出。我也试过一些相关解决方案,但都没效果,wrapper好像完全没法更新错误状态。
可能的解决方案
这里有几个可以尝试的方向,帮你排查问题:
触发原生表单submit事件,而非直接调用submitForm
直接调用子组件的submitForm方法可能跳过了Formik内部的一些验证触发逻辑,试试模拟表单的原生提交事件:// 替换原来的submitForm调用 getForm().simulate('submit');确认Yup验证规则正确配置
检查你的MyFormik组件里的validationSchema是否真的对name字段设置了必填规则,比如:import * as Yup from 'yup'; const validationSchema = Yup.object().shape({ name: Yup.string().required('Name is required'), // 确保这条规则存在 }); // 在Formik组件中使用这个schema <Formik initialValues={{ name: '' }} validationSchema={validationSchema} onSubmit={/* ... */} > {/* ... */} </Formik>用
waitFor替代wait(0),确保异步验证完成wait(0)有时候不够可靠,试试React Testing Library的waitFor来等待错误元素出现:import { waitFor } from '@testing-library/react'; // 替换原来的wait和update逻辑 await waitFor(() => { expect(wrapper.find('.error').exists()).toBeTruthy(); });检查错误元素的渲染逻辑
确保你的MyInnerForm组件正确渲染了错误信息,比如:// 在MyInnerForm中正确使用Formik的errors和touched const MyInnerForm = ({ errors, touched }) => ( <div> <input name="name" /> {touched.name && errors.name && <div className="error">{errors.name}</div>} </div> );
内容的提问来源于stack exchange,提问作者sebap
相关产品推荐
相关产品推荐

