首页 > 解决方案 > 使用 react-hook-form 时无法测试 onSubmit

问题描述

在编写单元测试用例以检查提交函数是否被调用时,我遇到了一个问题。我面临的问题与以下问题类似: https ://spectrum.chat/react-hook-form/help/solved-testing-the-onsubmit~364b8d79-c2f2-4d1c-a3ae-d56fed134128

但是,我使用的代码结构略有不同,因为我没有直接返回“表单组件”,而是返回包装在“FormContext”中的“表单组件”。

  export const CreateNewGame = () => {
  const [diceType, setDiceType] = useState(null);
  const { handleSubmit, register, errors, reset } = useForm({
    mode: 'onChange',
  });
  const submit = (data) => {
    console.log(data);
    reset({
      title: '',
      gameType: '',
      diceNumber: '',
    });
  };
  const dataSource = [
    'Settlers',
    'Catan',
    'Pandemic',
    'Ticket to Ride',
    'Risk',
    'Yatzy',
    'Dungeon and Dragons',
  ];
  useEffect(() => {}, [diceType]);
  return (
    <FormContext>
    <Form onSubmit={handleSubmit(submit)} data-testid='form'>
      <Input
        type='text'
        name='title'
        label='Titel'
        ref={register({ required: true })}
        error={errors.title}
      />
      <InputWithDatalist
        type='text'
        name='gameType'
        label='Ange spel'
        ref={register({ required: true })}
        error={errors.gameType}
        listArray={dataSource}
      />
      <Input
        type='text'
        name='diceNumber'
        label='Antal tärningar'
        ref={register({
          required: true,
          pattern: { value: /^[0-9]$/, message: 'Måste vara en siffra' },
        })}
        error={errors.diceNumber}
      />
      <DiceContainer>
        <DiceButton
          label='Prickar'
          activeClass={diceType === 'dots' ? true : false}
          icon='dice-five'
          onClick={() => setDiceType('dots')}
        />
        <DiceButton
          label='Siffror'
          activeClass={diceType === 'numbers' ? true : false}
          icon='dice-five'
          onClick={() => setDiceType('numbers')}
        />
      </DiceContainer>
      <GeneralButton type='submit'>Starta spel</GeneralButton>
    </Form>
    </FormContext>
  );
};

失败的测试如下:

it('testing', async () => {
    const props = {
          // props
}
    const onSubmit = jest.fn();
    const {
      getByTestId,
    } = render (
          <Provider store={store}>
           <FormContext>
          <CreateNewGame {...props} submit={onSubmit} />
        </FormContext>
      </Provider>
    );
    const form = getByTestId('form');
    fireEvent.submit(form);
    expect(onSubmit).toHaveBeenCalled();
  });

我得到的错误如下:

expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0

标签: reactjsunit-testingreact-testing-libraryreact-hook-formreact-forms

解决方案


在您的CreateNewGame组件中,您将一个submit道具传递给<CreateNewGame {...props} submit={onSubmit} />——在您的测试中,该道具包含对jest.fn()模拟的引用——但在组件定义本身中,该组件不接受任何道具。


推荐阅读