Skip to content

fix(jest-mock): remove leftover own accessor when restoring spyOn of an inherited getter/setter#16226

Open
LeSingh1 wants to merge 1 commit into
jestjs:mainfrom
LeSingh1:fix/spyon-inherited-accessor-restore
Open

fix(jest-mock): remove leftover own accessor when restoring spyOn of an inherited getter/setter#16226
LeSingh1 wants to merge 1 commit into
jestjs:mainfrom
LeSingh1:fix/spyon-inherited-accessor-restore

Conversation

@LeSingh1

@LeSingh1 LeSingh1 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

jest.spyOn(object, key, 'get' | 'set') supports spying on an accessor that lives on the prototype chain rather than on the object itself. When the accessor is inherited, the spy is installed by defining a new own property on the object via Object.defineProperty(object, propertyKey, descriptor). The restore step then re-defines that same own descriptor on the object instead of removing it.

The result is that after mockRestore, the object keeps an own accessor descriptor that shadows the prototype. The value read right after restore is still correct because the restored descriptor copied the prototype accessor, but the link to the prototype is gone, so later changes to the prototype accessor are no longer observed through the instance, and hasOwnProperty(key) stays true on something that was originally inherited.

The method branch of spyOn already handles this correctly: it tracks whether the method was an own property and deletes the own property on restore when it was inherited (see the existing isMethodOwner handling and the "should delete previously inexistent methods when restoring" test). This change applies the same approach to the accessor branch in _spyOnProperty: when the spied accessor was inherited, restoring now deletes the own property so the original prototype accessor is exposed again.

Test plan

Added two tests under packages/jest-mock/src/__tests__/index.test.ts in the spyOnProperty block, covering an inherited getter and an inherited setter. Each test spies on the inherited accessor, restores, and asserts that no own descriptor is left on the instance and that the prototype accessor is still in effect (including after the prototype accessor is later replaced).

Both tests fail on main and pass with this change. The full jest-mock unit suite passes.

yarn jest packages/jest-mock/src/__tests__/index.test.ts
Tests:       161 passed, 161 total

@netlify

netlify Bot commented Jun 4, 2026

Copy link
Copy Markdown

Deploy Preview for jestjs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 98bfe06
🔍 Latest deploy log https://app.netlify.com/projects/jestjs/deploys/6a2113e50d24b5000884a046
😎 Deploy Preview https://deploy-preview-16226--jestjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions Bot added the require-changelog If a PR does requires a changelog entry label Jun 4, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

babel-jest

npm i https://pkg.pr.new/babel-jest@16226

babel-plugin-jest-hoist

npm i https://pkg.pr.new/babel-plugin-jest-hoist@16226

babel-preset-jest

npm i https://pkg.pr.new/babel-preset-jest@16226

create-jest

npm i https://pkg.pr.new/create-jest@16226

@jest/diff-sequences

npm i https://pkg.pr.new/@jest/diff-sequences@16226

expect

npm i https://pkg.pr.new/expect@16226

@jest/expect-utils

npm i https://pkg.pr.new/@jest/expect-utils@16226

jest

npm i https://pkg.pr.new/jest@16226

jest-changed-files

npm i https://pkg.pr.new/jest-changed-files@16226

jest-circus

npm i https://pkg.pr.new/jest-circus@16226

jest-cli

npm i https://pkg.pr.new/jest-cli@16226

jest-config

npm i https://pkg.pr.new/jest-config@16226

@jest/console

npm i https://pkg.pr.new/@jest/console@16226

@jest/core

npm i https://pkg.pr.new/@jest/core@16226

@jest/create-cache-key-function

npm i https://pkg.pr.new/@jest/create-cache-key-function@16226

jest-diff

npm i https://pkg.pr.new/jest-diff@16226

jest-docblock

npm i https://pkg.pr.new/jest-docblock@16226

jest-each

npm i https://pkg.pr.new/jest-each@16226

@jest/environment

npm i https://pkg.pr.new/@jest/environment@16226

jest-environment-jsdom

npm i https://pkg.pr.new/jest-environment-jsdom@16226

@jest/environment-jsdom-abstract

npm i https://pkg.pr.new/@jest/environment-jsdom-abstract@16226

jest-environment-node

npm i https://pkg.pr.new/jest-environment-node@16226

@jest/expect

npm i https://pkg.pr.new/@jest/expect@16226

@jest/fake-timers

npm i https://pkg.pr.new/@jest/fake-timers@16226

@jest/get-type

npm i https://pkg.pr.new/@jest/get-type@16226

@jest/globals

npm i https://pkg.pr.new/@jest/globals@16226

jest-haste-map

npm i https://pkg.pr.new/jest-haste-map@16226

jest-jasmine2

npm i https://pkg.pr.new/jest-jasmine2@16226

jest-leak-detector

npm i https://pkg.pr.new/jest-leak-detector@16226

jest-matcher-utils

npm i https://pkg.pr.new/jest-matcher-utils@16226

jest-message-util

npm i https://pkg.pr.new/jest-message-util@16226

jest-mock

npm i https://pkg.pr.new/jest-mock@16226

@jest/pattern

npm i https://pkg.pr.new/@jest/pattern@16226

jest-phabricator

npm i https://pkg.pr.new/jest-phabricator@16226

jest-regex-util

npm i https://pkg.pr.new/jest-regex-util@16226

@jest/reporters

npm i https://pkg.pr.new/@jest/reporters@16226

jest-resolve

npm i https://pkg.pr.new/jest-resolve@16226

jest-resolve-dependencies

npm i https://pkg.pr.new/jest-resolve-dependencies@16226

jest-runner

npm i https://pkg.pr.new/jest-runner@16226

jest-runtime

npm i https://pkg.pr.new/jest-runtime@16226

@jest/schemas

npm i https://pkg.pr.new/@jest/schemas@16226

jest-snapshot

npm i https://pkg.pr.new/jest-snapshot@16226

@jest/snapshot-utils

npm i https://pkg.pr.new/@jest/snapshot-utils@16226

@jest/source-map

npm i https://pkg.pr.new/@jest/source-map@16226

@jest/test-result

npm i https://pkg.pr.new/@jest/test-result@16226

@jest/test-sequencer

npm i https://pkg.pr.new/@jest/test-sequencer@16226

@jest/transform

npm i https://pkg.pr.new/@jest/transform@16226

@jest/types

npm i https://pkg.pr.new/@jest/types@16226

jest-util

npm i https://pkg.pr.new/jest-util@16226

jest-validate

npm i https://pkg.pr.new/jest-validate@16226

jest-watcher

npm i https://pkg.pr.new/jest-watcher@16226

jest-worker

npm i https://pkg.pr.new/jest-worker@16226

pretty-format

npm i https://pkg.pr.new/pretty-format@16226

commit: 98bfe06

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

require-changelog If a PR does requires a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant