diff --git a/CHANGELOG.md b/CHANGELOG.md index 25e5ef463e13..045ac10d3456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ * `[jest-environment-jsdom]` Fix asynchronous test will fail due to timeout issue. ([#4669](https://github.com/facebook/jest/pull/4669)) ### Features +* `[jest-mock]` Add `timestamps` to mock state. ([#4866](https://github.com/facebook/jest/pull/4866)) * `[eslint-plugin-jest]` Add `prefer-to-have-length` lint rule. ([#4771](https://github.com/facebook/jest/pull/4771)) * `[jest-environment-jsdom]` [**BREAKING**] Upgrade to JSDOM@11 ([#4770](https://github.com/facebook/jest/pull/4770)) * `[jest-environment-*]` [**BREAKING**] Add Async Test Environment APIs, dispose is now teardown ([#4506](https://github.com/facebook/jest/pull/4506)) diff --git a/packages/jest-mock/README.md b/packages/jest-mock/README.md index ed0f1c612526..58920979bef4 100644 --- a/packages/jest-mock/README.md +++ b/packages/jest-mock/README.md @@ -80,11 +80,12 @@ the following members: ##### `.mock` -An object with two members, `calls`, and `instances`, which are both -lists. The items in the `calls` list are the arguments with which the +An object with three members, `calls`, `instances` and `timestamps`, which are +all lists. The items in the `calls` list are the arguments with which the function was called. The "instances" list stores the value of 'this' for each call to the function. This is useful for retrieving instances from a -constructor. +constructor. The `timestamps` list stores a number timestamp every time the +mock is called. ##### `.mockReturnValueOnce(value)` diff --git a/packages/jest-mock/src/__tests__/jest_mock.test.js b/packages/jest-mock/src/__tests__/jest_mock.test.js index 56106ca9d846..e081c8ecbc7e 100644 --- a/packages/jest-mock/src/__tests__/jest_mock.test.js +++ b/packages/jest-mock/src/__tests__/jest_mock.test.js @@ -390,6 +390,72 @@ describe('moduleMocker', () => { expect(fake(2)).toEqual(42); expect(fake(2)).toEqual(4); }); + + describe('timestamps', () => { + const RealDate = Date; + + beforeEach(() => { + global.Date = { + now: jest + .fn() + .mockImplementationOnce(() => 978391040765) + .mockImplementationOnce(() => 1262388620765), + }; + }); + + afterEach(() => { + global.Date = RealDate; + }); + + it('tracks timestamps made by mocks', () => { + const fn = moduleMocker.fn(); + expect(fn.mock.timestamps).toEqual([]); + + fn(1, 2, 3); + expect(fn.mock.timestamps[0]).toBe(978391040765); + + fn('a', 'b', 'c'); + expect(fn.mock.timestamps[1]).toBe(1262388620765); + }); + + it('supports clearing mock timestamps', () => { + const fn = moduleMocker.fn(); + expect(fn.mock.timestamps).toEqual([]); + + fn(1, 2, 3); + expect(fn.mock.timestamps).toEqual([978391040765]); + + fn.mockReturnValue('abcd'); + + fn.mockClear(); + expect(fn.mock.timestamps).toEqual([]); + + fn('a', 'b', 'c'); + expect(fn.mock.timestamps).toEqual([1262388620765]); + + expect(fn()).toEqual('abcd'); + }); + + it('supports clearing all mocks timestamps', () => { + const fn1 = moduleMocker.fn(); + fn1.mockImplementation(() => 'abcd'); + + fn1(1, 2, 3); + expect(fn1.mock.timestamps).toEqual([978391040765]); + + const fn2 = moduleMocker.fn(); + + fn2.mockReturnValue('abcde'); + fn2('a', 'b', 'c', 'd'); + expect(fn2.mock.timestamps).toEqual([1262388620765]); + + moduleMocker.clearAllMocks(); + expect(fn1.mock.timestamps).toEqual([]); + expect(fn2.mock.timestamps).toEqual([]); + expect(fn1()).toEqual('abcd'); + expect(fn2()).toEqual('abcde'); + }); + }); }); describe('getMockImplementation', () => { diff --git a/packages/jest-mock/src/index.js b/packages/jest-mock/src/index.js index 60776394ad41..33019e3edb51 100644 --- a/packages/jest-mock/src/index.js +++ b/packages/jest-mock/src/index.js @@ -24,6 +24,7 @@ export type MockFunctionMetadata = { type MockFunctionState = { instances: Array, calls: Array>, + timestamps: Array, }; type MockFunctionConfig = { @@ -279,6 +280,7 @@ class ModuleMockerClass { return { calls: [], instances: [], + timestamps: [], }; } @@ -313,6 +315,7 @@ class ModuleMockerClass { const mockConfig = mocker._ensureMockConfig(f); mockState.instances.push(this); mockState.calls.push(Array.prototype.slice.call(arguments)); + mockState.timestamps.push(Date.now()); if (this instanceof f) { // This is probably being called as a constructor prototypeSlots.forEach(slot => {