From 1ad9864ad72181932ee4433a2dce8d8b333661b8 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes da Costa Date: Mon, 1 Jul 2019 21:08:00 +0100 Subject: [PATCH] fix(jest-mock): fix mock restoration reassigning to previously unexisting prop (#8625) --- CHANGELOG.md | 1 + .../jest-mock/src/__tests__/index.test.ts | 26 +++++++++++++++++++ packages/jest-mock/src/index.ts | 8 +++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c57e8fc17c7..2bb3607b3b6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - `[jest-haste-map]` Don't throw on missing mapper in Node crawler ([#8558](https://github.com/facebook/jest/pull/8558)) - `[jest-core]` Fix incorrect `passWithNoTests` warning ([#8595](https://github.com/facebook/jest/pull/8595)) - `[jest-snapshots]` Fix test retries that contain snapshots ([#8629](https://github.com/facebook/jest/pull/8629)) +- `[jest-mock]` Fix incorrect assignments when restoring mocks in instances where they originally didn't exist ([#8631](https://github.com/facebook/jest/pull/8631)) ### Chore & Maintenance diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 64c47464be83..f665def33ea6 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -542,6 +542,32 @@ describe('moduleMocker', () => { }); }); + it('mocks the method in the passed object itself', () => { + const parent = {func: () => 'abcd'}; + const child = Object.create(parent); + + moduleMocker.spyOn(child, 'func').mockReturnValue('efgh'); + + expect(child.hasOwnProperty('func')).toBe(true); + expect(child.func()).toEqual('efgh'); + expect(parent.func()).toEqual('abcd'); + }); + + it('should delete previously inexistent methods when restoring', () => { + const parent = {func: () => 'abcd'}; + const child = Object.create(parent); + + moduleMocker.spyOn(child, 'func').mockReturnValue('efgh'); + + moduleMocker.restoreAllMocks(); + expect(child.func()).toEqual('abcd'); + + moduleMocker.spyOn(parent, 'func').mockReturnValue('jklm'); + + expect(child.hasOwnProperty('func')).toBe(false); + expect(child.func()).toEqual('jklm'); + }); + it('supports mock value returning undefined', () => { const obj = { func: () => 'some text', diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 7647b81c379a..be19de0df52f 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -1009,9 +1009,15 @@ class ModuleMockerClass { ); } + const isMethodOwner = object.hasOwnProperty(methodName); + // @ts-ignore overriding original method with a Mock object[methodName] = this._makeComponent({type: 'function'}, () => { - object[methodName] = original; + if (isMethodOwner) { + object[methodName] = original; + } else { + delete object[methodName]; + } }); // @ts-ignore original method is now a Mock