我试图模拟回调函数(Cb),并希望检查是否调用了1次。
我试过:
jest.useFakeTimers()
const cb = (t: number) => `message-${t}`
const spy = jest.fn(cb)
// This one also fails.
// jest.spyOn(React, 'useRef').mockReturnValue({ current: cb });
const { result } = renderHook(() => useTimer(3, cb))
await waitFor(() => expect(result.current[0]).toBe(3))
await waitFor(() => expect(result.current[1]).toBe('message-3'))
await waitFor(() => expect(spy).toBeCalledTimes(1)) // received 0const useTimer = (
startTimeSec: number,
cb: (currentSeconds: number) => string = (c) => '',
): [number, string] => {
const [timer, setTimer] = useState(startTimeSec)
const [intervalTime, setIntervalTime] = useState<null | number>(null)
const [message, setMessage] = useState<string>('')
const callback = React.useRef(cb)
useEffect(() => {
if (startTimeSec) {
setTimer(startTimeSec)
setMessage(callback.current(timer))
}
}, [startTimeSec])
//...
return [timer, message]
}有什么想法吗?
发布于 2021-03-17 03:52:05
您应该将模拟的回调函数spy传递给useTimers而不是cb。
此外,让我们回顾一下useRef()的概念
useRef返回一个可变的ref对象,该对象的
.current属性初始化为传递的参数(initialValue)。
这意味着模拟的cb函数将是.current属性的值。
例如。
userTimer.ts
import React, { useEffect, useState } from 'react';
const useTimer = (startTimeSec: number, cb: (currentSeconds: number) => string = (c) => ''): [number, string] => {
const [timer, setTimer] = useState(startTimeSec);
const [intervalTime, setIntervalTime] = useState<null | number>(null);
const [message, setMessage] = useState<string>('');
const callback = React.useRef(cb);
useEffect(() => {
if (startTimeSec) {
setTimer(startTimeSec);
setMessage(callback.current(timer));
}
}, [startTimeSec]);
return [timer, message];
};
export { useTimer };useTimer.test.ts
import { waitFor } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { useTimer } from './useTimer';
describe('useTimer', () => {
it('should pass', async () => {
const cb = (t: number) => `message-${t}`;
const spy = jest.fn(cb);
const { result } = renderHook(() => useTimer(3, spy));
await waitFor(() => expect(result.current[0]).toBe(3));
await waitFor(() => expect(result.current[1]).toBe('message-3'));
await waitFor(() => expect(spy).toBeCalledTimes(1));
});
});单元测试结果:
PASS examples/66452119/useTimer.test.ts
useTimer
✓ should pass (20 ms)
-------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------|---------|----------|---------|---------|-------------------
All files | 92.31 | 33.33 | 66.67 | 100 |
useTimer.ts | 92.31 | 33.33 | 66.67 | 100 | 3-10
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.931 shttps://stackoverflow.com/questions/66452119
复制相似问题