首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jest测试useInterval React钩子不工作

Jest测试useInterval React钩子不工作
EN

Stack Overflow用户
提问于 2021-03-13 22:31:55
回答 2查看 546关注 0票数 0

正在尝试测试自定义useInterval钩子,但jest.advanceTimersByTime(199);jest.advanceTimersToNextTimer(1);似乎不工作。

我记录jest.getTimerCount() anywhere,它返回0;

自定义挂钩:

代码语言:javascript
复制
import { useRef, useEffect } from 'react';

function useInterval(callback: () => void, delay: number | null) {
  const savedCallback = useRef<() => void | null>();

  // Remember the latest callback.
  useEffect(() => {
    savedCallback.current = callback;
  });

  // Set up the interval.
  useEffect(() => {
    function tick() {
      console.log("here"); // This never gets logged !!!!
      if (typeof savedCallback?.current !== 'undefined') {
        console.log(delay, savedCallback);
      }
    }

    if (delay !== null) {
      const id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

export default useInterval;

测试:

代码语言:javascript
复制
import useInterval from "./useInterval";
import { renderHook } from '@testing-library/react-hooks';


describe("useInterval Hook:", () => {
  let callback = jest.fn();


  beforeAll(() => {
    // we're using fake timers because we don't want to
    // wait a full second for this test to run.
    jest.useFakeTimers();
  });

  afterEach(() => {
    callback.mockRestore();
    jest.clearAllTimers();
  });

  afterAll(() => {
    jest.useRealTimers();
  });


  test('should init hook with delay', () => {
    const { result } = renderHook(() => useInterval(callback, 5000));

    expect(result.current).toBeUndefined();
    expect(setInterval).toHaveBeenCalledTimes(1);
    expect(setInterval).toHaveBeenCalledWith(expect.any(Function), 5000);
  });


  test('should repeatedly calls provided callback with a fixed time delay between each call', () => {
    const { result } = renderHook(() => useInterval(callback, 200));
    expect(callback).not.toHaveBeenCalled();

    // fast-forward time until 1s before it should be executed
    jest.advanceTimersByTime(199);
    expect(callback).not.toHaveBeenCalled(); // FAILS

    // jest.getTimerCount() here returns 0

    // fast-forward until 1st call should be executed
    jest.advanceTimersToNextTimer(1);
    expect(callback).toHaveBeenCalledTimes(1);

    // fast-forward until next timer should be executed
    jest.advanceTimersToNextTimer();
    expect(callback).toHaveBeenCalledTimes(2);

    // fast-forward until 3 more timers should be executed
    jest.advanceTimersToNextTimer(3);
    expect(callback).toHaveBeenCalledTimes(5);
  });
});
EN

回答 2

Stack Overflow用户

发布于 2021-03-13 23:03:36

我通过将jest.useFakeTimers();移到beforeEach块而不是beforeAll解决了这个问题。

票数 1
EN

Stack Overflow用户

发布于 2021-10-21 13:49:49

我为此苦苦挣扎了几个小时,终于找到了这篇文章。https://overreacted.io/making-setinterval-declarative-with-react-hooks/

只需逐字复制useInterval函数,然后将其与本文提供的语法一起使用。它工作正常,没有大惊小怪。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66614656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档