如何Mock Ant Design的useFormInstance?测试表单字段未触碰场景
问题:Mock Ant Design的useFormInstance以测试表单字段触摸状态
场景需求
需要Mock表单实例来验证!form?.isFieldsTouched()的逻辑,且不允许将form作为props传入组件。
组件代码
export const OCRActions = ({ isEditDisabled, set }: IOCRActionsProps) => { const form = useFormInstance(); return ( <Item noStyle shouldUpdate > {() => ( <Group> <Popconfirm title={( <div className='w-[200px]'> Do you want to apply made changes? Note that they may result in receipt reprocessing. </div> )} okText='Yes' cancelText='No' placement='bottom' onConfirm={handlePatchOCR(form, ocrFormValues, patchSnapsDetails)} disabled={ !form?.isFieldsTouched() } > <Button type='primary' loading={loading} disabled={ !form?.isFieldsTouched() } > Save </Button> </Popconfirm> </Group> )} </Item> ); };
无效的Mock尝试
尝试以下Mock方式后,useFormInstance()返回undefined:
jest.mock('antd', () => { const originalModule = jest.requireActual('antd'); return { ...originalModule, Form: { ...originalModule.Form, useFormInstance: jest.fn().mockReturnValueOnce({ getFieldsError: jest.fn().mockReturnValueOnce(() => []), isFieldsTouched: jest.fn().mockReturnValueOnce(true), }), }, }; });
解决方案
问题根源:Ant Design的useFormInstance是顶级导出,并非挂在Form对象下,之前的Mock路径错误。
方法1:直接Mock独立导出的useFormInstance
jest.mock('antd/es/form/useFormInstance', () => ({ __esModule: true, default: jest.fn().mockReturnValue({ isFieldsTouched: jest.fn().mockReturnValue(true), getFieldsError: jest.fn().mockReturnValue([]), }), }));
方法2:在antd根模块中Mock顶级导出
jest.mock('antd', () => { const originalModule = jest.requireActual('antd'); return { ...originalModule, useFormInstance: jest.fn().mockReturnValue({ isFieldsTouched: jest.fn().mockReturnValue(true), getFieldsError: jest.fn().mockReturnValue([]), }), }; });
完整测试用例示例
import { render, screen } from '@testing-library/react'; import { OCRActions } from './OCRActions'; import { useFormInstance } from 'antd'; // 提前Mock useFormInstance jest.mock('antd/es/form/useFormInstance', () => ({ __esModule: true, default: jest.fn(), })); describe('OCRActions', () => { test('表单未触摸时,Save按钮禁用', () => { (useFormInstance as jest.Mock).mockReturnValue({ isFieldsTouched: jest.fn().mockReturnValue(false), }); render(<OCRActions isEditDisabled={false} set={jest.fn()} />); expect(screen.getByText('Save')).toBeDisabled(); }); test('表单触摸后,Save按钮启用', () => { (useFormInstance as jest.Mock).mockReturnValue({ isFieldsTouched: jest.fn().mockReturnValue(true), }); render(<OCRActions isEditDisabled={false} set={jest.fn()} />); expect(screen.getByText('Save')).not.toBeDisabled(); }); });
关键提示
- 确认
useFormInstance的导出层级,它不属于Form组件的子属性,Mock时需匹配正确的导出路径。 - 可通过
jest.mock直接锁定具体导出文件,或在antd根模块中添加顶级Mock属性。
内容的提问来源于stack exchange,提问作者Denys Klymenko
相关产品推荐
相关产品推荐

