gpt4 book ai didi

javascript - Promise resolve 后如何正确测试 setTimeout

转载 作者:行者123 更新时间:2023-11-28 20:47:48 24 4
gpt4 key购买 nike

如何正确测试此功能。

  1. 设置超时
  2. 超时回调
  3. 和递归调用
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);
});
});

一些细节。

  1. 我很惊讶,但计时器在 it() 之间没有被清除。对我来说没有jest.clearAllTimers() .可能取决于 jsdom实现或 jest版本,我不知道。
  2. 没有await Promise.resolve()你的模拟 callback不要运行 .then部分。实际上它可能是await <anything else> , 我只看到 await Promise.resolve();看起来不如 await 42; 神奇.不管怎样,它的目的是冲洗microtasks queue虽然开 Jest 本身 does not provide直接的API。

关于javascript - Promise resolve 后如何正确测试 setTimeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59386719/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com