Тестирование компонента кнопки внутри компонента React.F C путем вызова его handleClick prop - PullRequest
0 голосов
/ 15 марта 2020

Я пытаюсь проверить изменение useState в компоненте функции React.

Вот как useState инициализируется в компоненте, и ниже это свойство называется toggleTimer, которое получает позвонил и уточнил, что я пытаюсь проверить. Внизу находится <MemoizedButton /> компонент, который имеет обработчик кликов handleClick, который вызывает функцию toggleTimer.

  const [state, setState] = useState({
    buttonType: 'start',
    clockHours: 0,
    clockMinutes: 0,
    clockSeconds: 0,
    timeInterval: false,
    totalSeconds: 0,
  });


...


  const toggleTimer = (): void => {
    if (state.buttonType === 'start') {
      setState(prevState => ({ ...prevState, buttonType: 'pause', timeInterval: true }));
      return;
    }
    setState(prevState => ({ ...prevState, buttonType: 'start', timeInterval: false }));
  };


...


<MemoizedButton kind={state.buttonType} handleClick={ (): void => toggleTimer() } />

Я пытаюсь проверить это путем насмешки useState. Я mount компонент <Timer /> с энзимом, а затем я нахожу кнопку на этом компоненте. Затем я пытаюсь вызвать опору handleClick для этой кнопки. Я ожидаю, что setState будет вызван один раз в этот момент, но он будет вызван 0 раз.


const wrapper = mount(<Timer />);
const timer = wrapper.find(Timer);


...


  describe('useState', () => {
    const setState = jest.fn();
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const useStateMock: any = (initState: any) => [initState, setState];

    it('should call setState', () => {
      jest.spyOn(React, 'useState').mockImplementation(useStateMock);
      const startButton = timer.find(Button).at(0);

      act(() => startButton.props().handleClick());

      expect(setState).toHaveBeenCalledTimes(1);
    });
  });

Я не уверен, имеет ли это значение, но что может усложнить то, что <MemoizedButton /> компонент, который ищет тест, запоминается (капитан, очевидно). Вот запомненная кнопка, а также то, что возвращает компонент Timer:

...

  const MemoizedButton = memo((props: ButtonProps) => {
    MemoizedButton.displayName = 'MemoizedButton';
    return <Button kind={ props.kind } handleClick={ props.handleClick } />;
  });

  return (
    <>
      <MemoizedButton kind={state.buttonType} handleClick={ (): void => toggleTimer() } />
      <MemoizedButton kind='stop' handleClick={ (): void => stopTimer() } />
    </>
  );
...