@ testing-library / react-hooks两次调用setTimeout

问题描述

这是我自定义的React-hook。

import { useEffect,useRef } from 'react'

function useInterval({ callback,interval,delay }) {
  const savedTimerId = useRef<NodeJS.Timeout>()

  useEffect(() => {
    const loop = () => {
      const res = callback()
      const nextIteration = () => {
        savedTimerId.current = setTimeout(loop,interval)
      }
      if (res instanceof Promise) {
        res.then(nextIteration)
      } else {
        nextIteration()
      }
    }
    let delayedTimerId: NodeJS.Timeout
    if (!delay) {
      loop()
    } else {
      delayedTimerId = setTimeout(loop,delay)
    }
    return () => {
      // @ts-ignore
      clearTimeout(savedTimerId.current)
      if (delayedTimerId) {
        clearTimeout(delayedTimerId)
      }
    }
  },[callback,delay])
}

export { useInterval }

这是单元测试

import { renderHook } from '@testing-library/react-hooks'
import { useInterval } from '../useInterval'

describe("Test scenarios for 'useInterval' hook",() => {
  jest.useFakeTimers()

  it("Should call 'callback' once",() => {
    const callback = jest.fn()
    const interval = 10000
    const params = { callback,interval }
    renderHook(() => useInterval(params))
    expect(setTimeout).toHaveBeenCalledTimes(1)
    expect(setTimeout).toHaveBeenCalledWith(expect.any(Function),interval)
  })
})

但这就是输出

Error: expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 1
Received number of calls: 2

我调试了此代码段。我发现在调用useInterval之前,已经触发了setTimeout

debug result

好像setTimeout在内部被调用了。怎么了?有什么想法吗?

解决方法

您绝对对private int countNodeLevel(int level,Node<E> n) { Node<E> curr=root; if(curr == null) { return 0; } if(level == 0) { return 1; } return ( countNodeLevel( level - 1,n.leftChild)+countNodeLevel(level - 1,n.rightChild)); } 正在幕后打电话给@testing-library/react-hooks,可以通过以下方式确认这一点:

setTimeout

您最好集中精力调用jest.useFakeTimers() renderHook(() => {}) expect(setTimeout).toHaveBeenCalledTimes(1) 而不是callback的次数:

setTimeout

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...