From 26bd716495412f5a5a258024da8cc54190954d46 Mon Sep 17 00:00:00 2001 From: rostog Date: Tue, 30 Apr 2019 16:52:14 +0200 Subject: [PATCH 1/5] fixed mockReturnValue overriding mockImplementationOnce --- .../jest-mock/src/__tests__/index.test.ts | 9 +++ packages/jest-mock/src/index.ts | 56 ++++--------------- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 64c47464be83..22988046dc90 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -994,6 +994,15 @@ describe('moduleMocker', () => { }); }); + it('mockReturnValue does not override mockImplementationOnce', () => { + const mockFn = jest + .fn() + .mockReturnValue(1) + .mockImplementationOnce(() => 2); + expect(mockFn()).toBe(2); + expect(mockFn()).toBe(1); + }); + test('mockImplementation resets the mock', () => { const fn = jest.fn(); expect(fn()).toBeUndefined(); diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 630dba527cf0..4898e9dd8d8f 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -71,8 +71,6 @@ type MockFunctionState> = { }; type MockFunctionConfig = { - isReturnValueLastSet: boolean; - defaultReturnValue: unknown; mockImpl: Function | undefined; mockName: string; specificReturnValues: Array; @@ -456,8 +454,6 @@ class ModuleMockerClass { private _defaultMockConfig(): MockFunctionConfig { return { - defaultReturnValue: undefined, - isReturnValueLastSet: false, mockImpl: undefined, mockName: 'jest.fn()', specificMockImpls: [], @@ -586,40 +582,22 @@ class ModuleMockerClass { return mockImpl && mockImpl.apply(this, arguments); } - const returnValue = mockConfig.defaultReturnValue; - // If return value is last set, either specific or default, i.e. - // mockReturnValueOnce()/mockReturnValue() is called and no - // mockImplementationOnce()/mockImplementation() is called after - // that. - // use the set return value. - if (mockConfig.specificReturnValues.length) { - return mockConfig.specificReturnValues.shift(); - } - - if (mockConfig.isReturnValueLastSet) { - return mockConfig.defaultReturnValue; - } - // If mockImplementationOnce()/mockImplementation() is last set, // or specific return values are used up, use the mock // implementation. - let specificMockImpl; - if (returnValue === undefined) { - specificMockImpl = mockConfig.specificMockImpls.shift(); - if (specificMockImpl === undefined) { - specificMockImpl = mockConfig.mockImpl; - } - if (specificMockImpl) { - return specificMockImpl.apply(this, arguments); - } + let specificMockImpl = mockConfig.specificMockImpls.shift(); + if (specificMockImpl === undefined) { + specificMockImpl = mockConfig.mockImpl; + } + if (specificMockImpl) { + return specificMockImpl.apply(this, arguments); } - // Otherwise use prototype implementation - if (returnValue === undefined && f._protoImpl) { + if (f._protoImpl) { return f._protoImpl.apply(this, arguments); } - return returnValue; + return undefined; })(); } catch (error) { // Store the thrown error so we can record it, then re-throw it. @@ -675,12 +653,9 @@ class ModuleMockerClass { return restore ? restore() : undefined; }; - f.mockReturnValueOnce = (value: T) => { + f.mockReturnValueOnce = (value: T) => // next function call will return this value or default return value - const mockConfig = this._ensureMockConfig(f); - mockConfig.specificReturnValues.push(value); - return f; - }; + f.mockImplementationOnce(() => value); f.mockResolvedValueOnce = (value: T) => f.mockImplementationOnce(() => Promise.resolve(value)); @@ -688,13 +663,9 @@ class ModuleMockerClass { f.mockRejectedValueOnce = (value: T) => f.mockImplementationOnce(() => Promise.reject(value)); - f.mockReturnValue = (value: T) => { + f.mockReturnValue = (value: T) => // next function call will return specified return value or this one - const mockConfig = this._ensureMockConfig(f); - mockConfig.isReturnValueLastSet = true; - mockConfig.defaultReturnValue = value; - return f; - }; + f.mockImplementation(() => value); f.mockResolvedValue = (value: T) => f.mockImplementation(() => Promise.resolve(value)); @@ -708,7 +679,6 @@ class ModuleMockerClass { // next function call will use this mock implementation return value // or default mock implementation return value const mockConfig = this._ensureMockConfig(f); - mockConfig.isReturnValueLastSet = false; mockConfig.specificMockImpls.push(fn); return f; }; @@ -718,8 +688,6 @@ class ModuleMockerClass { ): Mock => { // next function call will use mock implementation return value const mockConfig = this._ensureMockConfig(f); - mockConfig.isReturnValueLastSet = false; - mockConfig.defaultReturnValue = undefined; mockConfig.mockImpl = fn; return f; }; From a5c67e533eed764cae406c3454d2db7d77d11e9f Mon Sep 17 00:00:00 2001 From: rostog Date: Tue, 30 Apr 2019 17:38:53 +0200 Subject: [PATCH 2/5] updated changelog --- CHANGELOG.md | 1 + packages/jest-mock/src/__tests__/index.test.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6391a1227bfa..098f0dcd3450 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - `[expect]` Extract names of async and generator functions ([#8362](https://github.com/facebook/jest/pull/8362)) - `[jest-runtime]` Fix virtual mocks not being unmockable after previously being mocked ([#8396](https://github.com/facebook/jest/pull/8396)) - `[jest-transform]` Replace special characters in transform cache filenames to support Windows ([#8353](https://github.com/facebook/jest/pull/8353)) +- `[jest-mock]` Fix for mockReturnValue overriding mockImplementationOnce ([#placeholder](https://github.com/facebook/jest/pull/placeholder)) ### Chore & Maintenance diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 22988046dc90..976a8c616e2b 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -994,7 +994,7 @@ describe('moduleMocker', () => { }); }); - it('mockReturnValue does not override mockImplementationOnce', () => { + test('mockReturnValue does not override mockImplementationOnce', () => { const mockFn = jest .fn() .mockReturnValue(1) From def5719957d62972aacfdb027a3f17f67a3635fc Mon Sep 17 00:00:00 2001 From: rostog Date: Tue, 30 Apr 2019 18:38:05 +0200 Subject: [PATCH 3/5] added PR number in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 098f0dcd3450..fcf585b86552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ - `[expect]` Extract names of async and generator functions ([#8362](https://github.com/facebook/jest/pull/8362)) - `[jest-runtime]` Fix virtual mocks not being unmockable after previously being mocked ([#8396](https://github.com/facebook/jest/pull/8396)) - `[jest-transform]` Replace special characters in transform cache filenames to support Windows ([#8353](https://github.com/facebook/jest/pull/8353)) -- `[jest-mock]` Fix for mockReturnValue overriding mockImplementationOnce ([#placeholder](https://github.com/facebook/jest/pull/placeholder)) +- `[jest-mock]` Fix for mockReturnValue overriding mockImplementationOnce ([#8398](https://github.com/facebook/jest/pull/8398)) ### Chore & Maintenance From 3bb845a8ffa137ef4ee3feabe37eef0329abffb9 Mon Sep 17 00:00:00 2001 From: rostog Date: Thu, 18 Jul 2019 20:45:21 +0200 Subject: [PATCH 4/5] updated comment --- CHANGELOG.md | 1 - packages/jest-mock/src/index.ts | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1989f9c9b3e8..7ed139ed0da3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,6 @@ - `[jest-transform]` Replace special characters in transform cache filenames to support Windows ([#8353](https://github.com/facebook/jest/pull/8353)) - `[jest-config]` Allow exactly one project ([#7498](https://github.com/facebook/jest/pull/7498)) - ### Chore & Maintenance - `[expect]` Fix label and add opposite assertion for toEqual tests ([#8288](https://github.com/facebook/jest/pull/8288)) diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 33cfde2c1ee3..8afcd60b6a56 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -583,8 +583,7 @@ class ModuleMockerClass { } // If mockImplementationOnce()/mockImplementation() is last set, - // or specific return values are used up, use the mock - // implementation. + // implementation use the mock let specificMockImpl = mockConfig.specificMockImpls.shift(); if (specificMockImpl === undefined) { specificMockImpl = mockConfig.mockImpl; From e6948bd23854fbab9a8b9eddbc2908ee22427728 Mon Sep 17 00:00:00 2001 From: rostog Date: Thu, 18 Jul 2019 20:48:01 +0200 Subject: [PATCH 5/5] removed extra line from changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ed139ed0da3..77158d304f4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,6 @@ - `[jest-mock]` Fix incorrect assignments when restoring mocks in instances where they originally didn't exist ([#8631](https://github.com/facebook/jest/pull/8631)) - `[jest-mock]` Fix for mockReturnValue overriding mockImplementationOnce ([#8398](https://github.com/facebook/jest/pull/8398)) - ### Chore & Maintenance - `[jest-leak-detector]` remove code repeat ([#8438](https://github.com/facebook/jest/pull/8438)