[英]How properly test setTimeout after Promise resolve
如何正确测试此功能。
export function initScheduler(timeout: number, callback: () => Promise<void>): void {
setTimeout(() => {
callback().then(() => {
initScheduler(timeout, callback);
});
}, timeout);
}
我试过类似的东西
describe('initScheduler', () => {
it('should call on schedule', () => {
jest.useFakeTimers();
const timeout: number = 60000;
const callback: jest.Mock = jest.fn().mockResolvedValue(undefined);
initScheduler(timeout, callback);
expect(setTimeout).toHaveBeenCalledTimes(1);
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), timeout);
expect(callback).not.toBeCalled();
jest.advanceTimersByTime(timeout);
expect(callback).toBeCalled();
expect(setTimeout).toHaveBeenCalledTimes(2);
});
});
但最后的期望返回 1
不要专注于对setTimeout
断言。 专注于您的功能应该做什么。
describe('', () => {
jest.useFakeTimers();
const timeout = 300;
const callback = jest.fn();
beforeEach(() => {
jest.clearAllTimers();
callback
.mockClear()
.mockReturnValue(Promise.resolve());
});
it('runs callback only after delay given', () => {
initScheduler(timeout, callback);
jest.advanceTimersByTime(timeout - 1);
expect(callback).not.toHaveBeenCalled();
jest.advanceTimersByTime(2);
expect(callback).toHaveBeenCalledTimes(1);
});
it('reruns scheduler if callback been resolved successfully', async () => {
initScheduler(timeout, callback);
expect(callback).not.toHaveBeenCalled();
jest.advanceTimersByTime(timeout);
await Promise.resolve();
jest.advanceTimersByTime(timeout);
await Promise.resolve();
jest.advanceTimersByTime(timeout);
await Promise.resolve();
expect(callback).toHaveBeenCalledTimes(3);
});
it('stops scheduler if callback rejected', async () => {
callback.mockReturnValue(Promise.reject());
initScheduler(timeout, callback);
jest.advanceTimersByTime(timeout);
await Promise.resolve();
jest.advanceTimersByTime(timeout);
await Promise.resolve();
expect(callback).toHaveBeenCalledTimes(1);
});
});
一些细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.