From a34e4b69630ce713c0c25a5af66734c96b25f0c7 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Tue, 3 Aug 2021 09:09:46 +0200 Subject: [PATCH] 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..5c1159214359 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 not rely on hasOwnProperty', () => { + 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);