Aja*_*esh 2 javascript ecmascript-6 es6-promise jestjs babel-jest
这是我用来延迟进程的代码(用于退避)
export function promiseDelay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
Run Code Online (Sandbox Code Playgroud)
我想测试它,但我不能。我尝试使用 fakeTimers 但我的测试从未结束。
test('promiseDelay delays for 1s', async (done) => {
jest.useFakeTimers();
Promise.resolve().then(() => jest.advanceTimersByTime(100));
await promiseDelay(100);
});
Run Code Online (Sandbox Code Playgroud)
Bri*_*ams 13
promiseDelay返回Promise解析后,ms所以叫spy中then和测试,看是否spy已经被不同的时间间隔之后调用:
describe('promiseDelay', () => {
beforeEach(() => { jest.useFakeTimers(); });
afterEach(() => { jest.useRealTimers(); });
test('should not resolve until timeout has elapsed', async () => {
const spy = jest.fn();
promiseDelay(100).then(spy); // <= resolve after 100ms
jest.advanceTimersByTime(20); // <= advance less than 100ms
await Promise.resolve(); // let any pending callbacks in PromiseJobs run
expect(spy).not.toHaveBeenCalled(); // SUCCESS
jest.advanceTimersByTime(80); // <= advance the rest of the time
await Promise.resolve(); // let any pending callbacks in PromiseJobs run
expect(spy).toHaveBeenCalled(); // SUCCESS
});
});
Run Code Online (Sandbox Code Playgroud)
请注意,测试代码是同步的,并且Timer Mocks使setTimeout同步但then 将回调PromiseJobs排队,因此如果spy已调用,则需要允许任何排队的回调在测试之前运行。
这可以通过使用async测试函数并调用await已解决的方法来完成,该函数在测试继续之前允许任何挂起的回调运行Promise结束时有效地将测试的其余部分排队PromiseJobs。
此处的回答中提供了有关 promise 和假计时器如何交互的其他信息。