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

React测试:如何mock react-hook-form的useFormContext方法?

解决方案

方案1:使用FormProvider包裹测试组件(优先推荐)

该方案完全模拟生产环境中父组件调用子组件的逻辑,无需mock hook,测试结果更准确:

import { useForm, FormProvider } from 'react-hook-form';
// 导入你的类型定义
import type { CustomerProfileFormData } from '你的类型定义文件路径';

it('should render properly', () => {
    // 初始化表单实例,和父组件实际用法一致
    const formMethods = useForm<CustomerProfileFormData>();
    render(
        <FormProvider {...formMethods}>
            <AddressDetails isEdit={false} />
        </FormProvider>
    );
    expect(screen.getByTestId('address-details')).toBeInTheDocument();
});

方案2:手动mock useFormContext hook

如果需要隔离表单逻辑做单独测试,可以直接mock hook返回值:

  1. 在测试文件顶部mock react-hook-form模块:
jest.mock('react-hook-form', () => ({
  ...jest.requireActual('react-hook-form'),
  useFormContext: jest.fn(() => ({
    // 按子组件实际用到的方法补齐mock内容
    register: jest.fn(),
    // 如果用到其他方法也可以在这里添加,比如:
    // handleSubmit: jest.fn(),
    // formState: { errors: {} }
  }))
}));
  1. 如果不同测试用例需要自定义返回值,可以单独覆盖:
import { useFormContext } from 'react-hook-form';

it('should render error when address is invalid', () => {
  (useFormContext as jest.Mock).mockReturnValueOnce({
    register: jest.fn(),
    formState: {
      errors: {
        address: { message: '地址不能为空' }
      }
    }
  });

  render(<AddressDetails isEdit={false} />);
  // 你的断言逻辑
});

注意事项

  • 如果你选择方案2,必须保证mock返回值包含所有子组件中从useFormContext解构出来的属性,否则依然会出现解构报错
  • 没有特殊隔离需求的场景下优先使用方案1,更贴近真实运行逻辑,维护成本更低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 14:27:03