1. // __tests__/timerGame-test.js
  2. 'use strict';
  3. jest.useFakeTimers();
  4. test('waits 1 second before ending the game', () => {
  5. const timerGame = require('../timerGame');
  6. timerGame();
  7. expect(setTimeout).toHaveBeenCalledTimes(1);
  8. expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 1000);

在这里我们通过jest.useFakeTimers();来模拟定时器函数。 通过mock函数可以模拟setTimeout和其他的定时器函数。 如果你需要在一个文件或一个describe块中运行多次测试,可以在每次测试前手动添加jest.useFakeTimers();,或者在中添加。 如果不这样做的话将导致内部的定时器不被重置。

在某些场景下你可能还需要“循环定时器”——在定时器的callback函数中再次设置一个新定时器。 对于这种情况,如果将定时器一直运行下去那将陷入死循环,所以在此场景下不应该使用jest.runAllTimers() For these cases you might use jest.runOnlyPendingTimers():

  1. // infiniteTimerGame.js
  2. 'use strict';
  3. function infiniteTimerGame(callback) {
  4. console.log('Ready....go!');
  5. setTimeout(() => {
  6. console.log("Time's up! 10 seconds before the next game starts...");
  7. callback && callback();
  8. // Schedule the next game in 10 seconds
  9. setTimeout(() => {
  10. infiniteTimerGame(callback);
  11. }, 10000);
  12. module.exports = infiniteTimerGame;
从22.0.0版本的Jest开始,runTimersToTime被重命名为advanceTimersByTime。
  1. // timerGame.js
  2. 'use strict';
  3. function timerGame(callback) {
  4. console.log('Ready....go!');
  5. setTimeout(() => {
  6. console.log("Time's up -- stop!");
  7. callback && callback();
  8. }, 1000);
  9. }

Lastly, it may occasionally be useful in some tests to be able to clear all of the pending timers. For this, we have jest.clearAllTimers().