问题描述
这是我自定义的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
。
好像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