我正在学习用 jest 进行测试,我想出了这个方法:jest.advanceTimersToNextTimer
。 Jest 的手册说:
Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run. Optionally, you can provide steps, so it will run steps amount of next timeouts/intervals.
但我不清楚它是如何工作的。有人可以解释一下它的作用,并给出一个使用示例吗?谢谢。
最佳答案
使用时jest.advanceTimersToNextTimer(steps) ,您不再需要手动提供毫秒来运行已通过 setTimeout()
或 setInterval()
排队的宏任务。正如医生所说:
Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run.
此外,您可以为 jest.advanceTimersToNextTimer()
方法提供 steps
,以便它将运行 steps
下一个超时/间隔时间。请参阅“应按步骤通过”
测试用例。默认步骤
为1
,请参阅here
使用jest.advanceTimersByTime()
时,如果有大量宏任务通过setTimeout()
或setInterval()
排队,如果我们想要提前所有计时器,我们必须自己计算 msToRun
毫秒。这也许是非常麻烦的。请参阅“应通过提前所有计时器”
测试用例。
此外,有时您可能想在计时器执行之前检查状态。在这种情况下,您必须使用 jest.advanceTimersByTime()
,请参阅此 real world example ,定时器是200毫秒,但他们在199毫秒内检查快进的状态。
jest.advanceTimersToNextTimer()
使用 click.next() @sinonjs/faker-timers
包底层的方法。
Advances the clock to the the moment of the first scheduled timer, firing it.
jest.advanceTimersByTime()只需使用 clock.tick(time)底层。
请参阅下面的示例,三个测试用例以不同的方式执行相同的操作。
describe('71667406', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
describe('advanceTimersToNextTimer', () => {
test('should pass', () => {
const runOrder: Array<string> = [];
const mock1 = jest.fn(() => runOrder.push('mock1'));
const mock2 = jest.fn(() => runOrder.push('mock2'));
const mock3 = jest.fn(() => runOrder.push('mock3'));
const mock4 = jest.fn(() => runOrder.push('mock4'));
setTimeout(mock1, 100);
setTimeout(mock2, 0);
setTimeout(mock3, 0);
setInterval(() => {
mock4();
}, 200);
jest.advanceTimersToNextTimer();
// Move forward to t=0
expect(runOrder).toEqual(['mock2', 'mock3']);
jest.advanceTimersToNextTimer();
// Move forward to t=100
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1']);
jest.advanceTimersToNextTimer();
// Move forward to t=200
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1', 'mock4']);
jest.advanceTimersToNextTimer();
// Move forward to t=400
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1', 'mock4', 'mock4']);
});
test('should pass with steps', () => {
const runOrder: Array<string> = [];
const mock1 = jest.fn(() => runOrder.push('mock1'));
const mock2 = jest.fn(() => runOrder.push('mock2'));
const mock3 = jest.fn(() => runOrder.push('mock3'));
const mock4 = jest.fn(() => runOrder.push('mock4'));
setTimeout(mock1, 100);
setTimeout(mock2, 0);
setTimeout(mock3, 0);
setInterval(() => {
mock4();
}, 200);
jest.advanceTimersToNextTimer(4);
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1', 'mock4', 'mock4']);
});
});
describe('advanceTimersByTime', () => {
test('should pass', () => {
const runOrder: Array<string> = [];
const mock1 = jest.fn(() => runOrder.push('mock1'));
const mock2 = jest.fn(() => runOrder.push('mock2'));
const mock3 = jest.fn(() => runOrder.push('mock3'));
const mock4 = jest.fn(() => runOrder.push('mock4'));
setTimeout(mock1, 100);
setTimeout(mock2, 0);
setTimeout(mock3, 0);
setInterval(() => {
mock4();
}, 200);
jest.advanceTimersByTime(0);
// Move forward to t=0
expect(runOrder).toEqual(['mock2', 'mock3']);
jest.advanceTimersByTime(100);
// Move forward to t=100
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1']);
jest.advanceTimersByTime(200);
// Move forward to t=200
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1', 'mock4']);
jest.advanceTimersByTime(200);
// Move forward to t=400
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1', 'mock4', 'mock4']);
});
test('should pass advance all timers', () => {
const runOrder: Array<string> = [];
const mock1 = jest.fn(() => runOrder.push('mock1'));
const mock2 = jest.fn(() => runOrder.push('mock2'));
const mock3 = jest.fn(() => runOrder.push('mock3'));
const mock4 = jest.fn(() => runOrder.push('mock4'));
setTimeout(mock1, 100);
setTimeout(mock2, 0);
setTimeout(mock3, 0);
setInterval(() => {
mock4();
}, 200);
// We need to calculate it, this is very cumbersome
jest.advanceTimersByTime(0 + 100 + 200 + 200);
expect(runOrder).toEqual(['mock2', 'mock3', 'mock1', 'mock4', 'mock4']);
});
});
});
测试结果:
PASS stackoverflow/71667406/index.test.ts
71667406
advanceTimersToNextTimer
✓ should pass (4 ms)
✓ should pass with steps
advanceTimersByTime
✓ should pass (1 ms)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 1.242 s
也希望Jest官方能够给出更多的例子来说明API的使用场景。
关于javascript - 解释 "jest.advanceTimersToNextTimer ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71667406/