reactjs React -如何模拟useFormContext(react-hook-form)

sr4lhrrt  于 2023-04-11  发布在  React
关注(0)|答案(4)|浏览(227)

我在一个子组件中使用useFormContext。这是它的代码:

const { register } = useFormContext<CustomerProfileFormData>();

我怎样才能模拟useFormContext,以便我可以测试子组件。这是测试

it('should render properly', () => {
    render(<AddressDetails isEdit={false} />);
    expect(screen.getByTestId('address-details')).toBeInTheDocument();
});

我得到这个错误TypeError:无法解构“(0,_reactHookForm.useFormContext)(...)”的属性“register”,因为它是null.Jest。
这是有道理的,因为我没有模仿useFormContext。我怎么能模仿它呢?任何帮助将不胜感激。

7uzetpgm

7uzetpgm1#

您可以模仿其他响应中指示的上下文方法,或者可以通过在测试中创建一个特殊的 Package 器组件来为组件提供实际的FormContext,如下所示:

it('should do something', () => {
  const Wrapper = (props) => {
    const formMethods = useForm<CustomerProfileFormData>();

    return (
      <FormProvider {...formMethods}>
        {props.children}
      </FormProvider>
    );
  };

  render(
    <Wrapper>
      <AddressDetails />
    </Wrapper>
  );

  // your assertions here ... 
})

如果你想验证你的组件在表单值上的行为是否正确,你可以用预先配置的数据覆盖getValues方法。

const mockedGetValues = (key: string) => {
   // return test data for form key
}

return (
  <FormProvider {...formMethods} getValues={mockedGetValues}>
    {props.children}
  </FormProvider>
);
tyg4sfes

tyg4sfes2#

为了使useFormContext方法在测试中工作,RHF建议使用<FormProvider>Github-How to Test FormProvider / useFormContext) Package 它。
使用<FormProvider> Package 您的组件,并提供如下所需的方法:

render(
  <FormProvider {...({ setValue: () => jest.fn() } as any)}>
    <AddressDetails isEdit={false} />
  </FormProvider>
);
qeeaahzv

qeeaahzv3#

我找到了一个适合我的解决方案:

jest.mock( "react-hook-form", () => ( {
  ...jest.requireActual( "react-hook-form" ),
  useFormContext: () => ( {
    handleSubmit: () => jest.fn(),
    getValues: () => jest.fn(),
  } ),
} ) );
velaa5lx

velaa5lx4#

要模拟react-hook-form v7,您可以执行以下操作

jest.mock('react-hook-form', () => ({
  ...jest.requireActual('react-hook-form'),
  useFormContext: () => ({
    handleSubmit: () => jest.fn(),
    control: {
      register: jest.fn(),
      unregister: jest.fn(),
      getFieldState: jest.fn(),
      _names: {
        array: new Set('test'),
        mount: new Set('test'),
        unMount: new Set('test'),
        watch: new Set('test'),
        focus: 'test',
        watchAll: false,
      },
      _subjects: {
        watch: jest.fn(),
        array: jest.fn(),
        state: jest.fn(),
      },
      _getWatch: jest.fn(),
      _formValues: ['test'],
      _defaultValues: ['test'],
    },
    getValues: () => {
      return [];
    },
    setValue: () => jest.fn(),
    formState: () => jest.fn(),
    watch: () => jest.fn(),
  }),
  Controller: () => [],
  useSubscribe: () => ({
    r: { current: { subject: { subscribe: () => jest.fn() } } },
  }),
}));

相关问题