From d614bb1cc001efb357c105ded127612ad25217d1 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Tue, 3 Aug 2021 09:09:46 +0200 Subject: [PATCH 1/2] fix: spyOn should not rely on hasOwnProperty from the spied object The `spyOn` function uses `hasOwnProperty` from the spied object, but this method can be unavailable, for example if the object has the `null` prototype, or if it is a proxy that filters some keys. This arises in Vue 3 projects where the proxies returned by the framework do not expose all methods, and forces the testing library to manually patch the proxies with `hasOwnProperty` to let Jest do its work https://github.com/vuejs/vue-test-utils-next/blob/23d3d3e1f4178a87de5023f5255e0623653affdc/src/mount.ts#L493-L495 This commit changes the code to use `Object.prototype.hasOwnProperty` and fixes this issue. --- CHANGELOG.md | 4 ++++ packages/jest-mock/src/__tests__/index.test.ts | 12 ++++++++++++ packages/jest-mock/src/index.ts | 5 ++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b1d88a6a8d..ad4935540360 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ - `[docs]` Correct expects.assertions documentation by adding async/await for asynchronous function. +### Fixes + +- `[jest-mock]` Fix `spyOn` to use `Object.prototype.hasOwnProperty` [#11721](https://github.com/facebook/jest/pull/11721) + ## 27.0.6 ### Fixes diff --git a/packages/jest-mock/src/__tests__/index.test.ts b/packages/jest-mock/src/__tests__/index.test.ts index 0266d24f2b7b..ddd6af4f1fba 100644 --- a/packages/jest-mock/src/__tests__/index.test.ts +++ b/packages/jest-mock/src/__tests__/index.test.ts @@ -1216,6 +1216,18 @@ describe('moduleMocker', () => { expect(originalCallArguments[1]).toBe(secondArg); expect(spy).not.toHaveBeenCalled(); }); + + it('should work with object of null prototype', () => { + const Foo = Object.assign(Object.create(null), { + foo() {}, + }); + + const spy = moduleMocker.spyOn(Foo, 'foo'); + + Foo.foo(); + + expect(spy).toHaveBeenCalled(); + }); }); describe('spyOnProperty', () => { diff --git a/packages/jest-mock/src/index.ts b/packages/jest-mock/src/index.ts index 1b0330421124..885bf2ecf2d4 100644 --- a/packages/jest-mock/src/index.ts +++ b/packages/jest-mock/src/index.ts @@ -976,7 +976,10 @@ export class ModuleMocker { ); } - const isMethodOwner = object.hasOwnProperty(methodName); + const isMethodOwner = Object.prototype.hasOwnProperty.call( + object, + methodName, + ); let descriptor = Object.getOwnPropertyDescriptor(object, methodName); let proto = Object.getPrototypeOf(object); From 87756cc976b90510685cc858e4afbc72fc5a03a5 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 16 Aug 2021 10:22:09 +0200 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4935540360..ccc92bfcac79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixes +- `[jest-mock]` Fix `spyOn` to use `Object.prototype.hasOwnProperty` [#11721](https://github.com/facebook/jest/pull/11721) + ### Chore & Maintenance ### Performance @@ -14,10 +16,6 @@ - `[docs]` Correct expects.assertions documentation by adding async/await for asynchronous function. -### Fixes - -- `[jest-mock]` Fix `spyOn` to use `Object.prototype.hasOwnProperty` [#11721](https://github.com/facebook/jest/pull/11721) - ## 27.0.6 ### Fixes