Jest useFakeTimer
Jest’s useFakeTimers function is used to mock timers in JavaScript. This is particularly useful when you have code that uses setTimeout, setInterval, or Date objects, and you want to control the passage of time in your tests.
Basic Usage
To use Jest’s useFakeTimers function, you need to call it before the code you want to test. You can then advance the timers using the advanceTimersByTime function.
Advance Timers
待测试代码:
1 | somethingDone = false; |
测试代码:
1 | it('test doSomethingAfter1Second', () => { |
Run all timers
Jest.runAllTimers() will run all pending timers. This is useful when you have multiple timers that need to be run in sequence. (Note, it will not work for nested timers)
待测试代码:
1 | somethingDone = false; |
测试代码:
1 | it('test doSomethingAfter1Second', () => { |
Run only pending timers
There are also scenarios where you might have a recursive timer – that is a timer that sets a new timer in its own callback.
Jest.runOnlyPendingTimers() will only run the timers that are currently pending. This is useful when you want to run the timers that are currently in the queue, but not the ones that are scheduled to run in the future.
If you use jest.runAllTimers
here, it will run all the timers and end up with an infinite loop.
待测试代码:
1 | firstRound = false; |
测试代码:
1 | it('test infiniteTimerGame', () => { |
Selective faking
Sometimes your code may require to avoid overwriting the original implementation of one or another API. If that is the case, you can use doNotFake
option. For example, here is how you could provide a custom mock function for performance.mark()
in jsdom environment:
1 | const mockPerformanceMark = jest.fn(); |
Restore timers
After you have finished testing, you should restore the original timers using jest.useRealTimers(), This can be done by invoking jest.useRealTimers() in the afterEach hook.
1 | afterEach(() => { |
You can also do this at the end of a test:
1 | it('test doSomethingAfter1Second', () => { |