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

Ami*_*pal 13 reactjs react-hook-form

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

const { register } = useFormContext<CustomerProfileFormData>();
Run Code Online (Sandbox Code Playgroud)

我如何模拟 useFormContext 以便我可以测试子组件。这是测试

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

我收到此错误 TypeError: Cannot destruct property 'register' of '(0 , _reactHookForm.useFormContext)(...)' 因为它是 null.Jest。

这是有道理的,因为我没有模拟 useFormContext 。我怎样才能模拟它?任何帮助将不胜感激。

Joh*_*rra 16

您可以模拟其他响应中所示的上下文方法,也可以通过在测试中创建一个临时包装器组件来为您的组件提供实际的 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 ... 
})
Run Code Online (Sandbox Code Playgroud)

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

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

return (
  <FormProvider {...formMethods} getValues={mockedGetValues}>
    {props.children}
  </FormProvider>
);
Run Code Online (Sandbox Code Playgroud)


小智 2

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

jest.mock( "react-hook-form", () => ( {
  ...jest.requireActual( "react-hook-form" ),
  useFormContext: () => ( {
    handleSubmit: () => jest.fn(),
    getValues: () => jest.fn(),
  } ),
} ) );
Run Code Online (Sandbox Code Playgroud)