Тестирование с использованием useEffect и jest.useFakeTimer () - PullRequest
1 голос
/ 07 мая 2019

Я пытаюсь создать простой компонент переподготовки

Refresher.js

import { useEffect } from 'react';

const Refresher = ({ onRefresh }) => {
  useEffect(() => {
    const id = setInterval(onRefresh, 60000);
    return () => {
      clearInterval(id);
    };
  }, [onRefresh]);

  return null;
};

export default Refresher;

Однако, когда я пытаюсь протестировать его, используя jest.useFakeTimers(), почему-то это не работает. Заглушка не вызывается даже после jest.runOnlyPendingTimers()

import React from 'react';
import renderer from 'react-test-renderer';
import Refresher from '../Refresher';

describe('Refresher', () => {
  test('should refresh the result every 60 seconds', () => {
    jest.useFakeTimers();

    const onRefreshSpy = jest.fn();

    const refresher = renderer.create(<Refresher onRefresh={onRefreshSpy} />);

    expect(onRefreshSpy).not.toHaveBeenCalled();
    jest.runOnlyPendingTimers();
    refresher.update(); // Trying force update here

    expect(onRefreshSpy).toHaveBeenCalled();
  });
});

Если не ошибаюсь, интервал не будет работать, если компонент не будет обновлен, поэтому я попытался использовать refresher.update(), но, похоже, он на самом деле не работает.

Кто-нибудь знает, как исправить тест здесь?

1 Ответ

1 голос
/ 07 мая 2019

Вам просто нужно смоделировать useLayoutEffect вместо useEffect. Смотрите выпуск здесь

describe('Refresher', () => {
  beforeAll(() => jest.spyOn(React, 'useEffect').mockImplementation(React.useLayoutEffect))
  test('should refresh the result every 60 seconds', () => {
    jest.useFakeTimers();
    const onRefreshSpy = jest.fn();
    const refresher = renderer.create(<Refresher onRefresh={onRefreshSpy} />);
    expect(onRefreshSpy).not.toHaveBeenCalled();
    jest.runOnlyPendingTimers();
    expect(onRefreshSpy).toHaveBeenCalled();
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...