From 1ba52b9eaa435c908c50c02727f8b3a6fd351649 Mon Sep 17 00:00:00 2001 From: Jochen Schoubben Date: Tue, 13 Jul 2021 22:41:33 +0200 Subject: [PATCH 1/3] Add options object with ignore property to modern useFakeTimers function --- examples/async/__tests__/user.test.js | 6 +++++ .../src/__tests__/modernFakeTimers.test.ts | 24 +++++++++++++++++++ .../jest-fake-timers/src/modernFakeTimers.ts | 14 +++++++---- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/examples/async/__tests__/user.test.js b/examples/async/__tests__/user.test.js index a81de93b1cd4..b39d023b5079 100644 --- a/examples/async/__tests__/user.test.js +++ b/examples/async/__tests__/user.test.js @@ -68,3 +68,9 @@ it('tests error with async/await and rejects', async () => { error: 'User with 3 not found.', }); }); + +it('works with fakeTimers', async () => { + jest.useFakeTimers('modern', {ignore: ['nextTick']}); + expect.assertions(1); + return user.getUserName(4).then(data => expect(data).toEqual('Mark')); +}); diff --git a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts index a731c594104c..3f3d720fdacf 100644 --- a/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts +++ b/packages/jest-fake-timers/src/__tests__/modernFakeTimers.test.ts @@ -798,6 +798,30 @@ describe('FakeTimers', () => { expect(global.setImmediate).not.toBe(nativeSetImmediate); expect(global.clearImmediate).not.toBe(nativeClearImmediate); }); + + it('ignores timer functions from the ignore option', () => { + const nativeSetTimeout = jest.fn(); + const nativeClearTimeout = jest.fn(); + const nativeNextTick = jest.fn(); + process.nextTick = nativeNextTick; + const global = { + Date, + clearTimeout: nativeClearTimeout, + process, + setTimeout: nativeSetTimeout, + }; + + const timers = new FakeTimers({global}); + timers.useFakeTimers({ + ignore: ['nextTick', 'clearTimeout'], + }); + + // Ignored functions don't get mocked + expect(global.process.nextTick).toBe(nativeNextTick); + expect(global.clearTimeout).toBe(nativeClearTimeout); + // check if other functions are still being mocked + expect(global.setTimeout).not.toBe(nativeSetTimeout); + }); }); describe('getTimerCount', () => { diff --git a/packages/jest-fake-timers/src/modernFakeTimers.ts b/packages/jest-fake-timers/src/modernFakeTimers.ts index 80cd292a69be..8b38315c0ad5 100644 --- a/packages/jest-fake-timers/src/modernFakeTimers.ts +++ b/packages/jest-fake-timers/src/modernFakeTimers.ts @@ -12,6 +12,10 @@ import { } from '@sinonjs/fake-timers'; import {StackTraceConfig, formatStackTrace} from 'jest-message-util'; +interface ModernFakeTimersOptions { + ignore?: Array; +} + export default class FakeTimers { private _clock!: InstalledClock; private _config: StackTraceConfig; @@ -93,11 +97,13 @@ export default class FakeTimers { } } - useFakeTimers(): void { + useFakeTimers(options: ModernFakeTimersOptions = {}): void { if (!this._fakingTime) { - const toFake = Object.keys(this._fakeTimers.timers) as Array< - keyof FakeTimerWithContext['timers'] - >; + const toFake = Object.keys(this._fakeTimers.timers).filter( + // This is a simple attempt to fix the issue when using fakeTimers in combination with promises + // Developers can now add the nextTick function to the list timers not to mock + timerFunc => !(options?.ignore || []).includes(timerFunc), + ) as Array; this._clock = this._fakeTimers.install({ loopLimit: this._maxLoops, From c94b638b9350b55929fc9b1b10ef4b1f5582e2d7 Mon Sep 17 00:00:00 2001 From: Jochen Schoubben Date: Tue, 13 Jul 2021 22:45:25 +0200 Subject: [PATCH 2/3] Added changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b1d88a6a8d..7f8dc8ed88d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## master ### Features +- `[@jest/fake-timers]` Add options object with ignore property to modern useFakeTimers function. ([#11661](https://github.com/facebook/jest/pull/11661)) ### Fixes From 569028af5f6398c30c8b3710deef86ae715bbf67 Mon Sep 17 00:00:00 2001 From: Jochen Schoubben Date: Wed, 14 Jul 2021 00:34:53 +0200 Subject: [PATCH 3/3] Removed example code because it fails the tests --- examples/async/__tests__/user.test.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/async/__tests__/user.test.js b/examples/async/__tests__/user.test.js index b39d023b5079..a81de93b1cd4 100644 --- a/examples/async/__tests__/user.test.js +++ b/examples/async/__tests__/user.test.js @@ -68,9 +68,3 @@ it('tests error with async/await and rejects', async () => { error: 'User with 3 not found.', }); }); - -it('works with fakeTimers', async () => { - jest.useFakeTimers('modern', {ignore: ['nextTick']}); - expect.assertions(1); - return user.getUserName(4).then(data => expect(data).toEqual('Mark')); -});