Skip to content

Cannot spyOn inherited getters/setters #7801

@david2tm

Description

@david2tm

Describe the bug

I hope I gave the right title.

Problem

Consider the following:

import { spyOn } from 'tinyspy'

class A {
  _a = 0
  get a() {
    return this._a
  }
  set a(value) {
    this._a = value
  }
}

class Foo extends A {
}


    const a = new Foo()
    spyOn(a, { getter: 'a' }, () => 100)
    console.log(a.a) // OK
    a.a = 2 // fails here <----

with error: TypeError: Cannot set property a of #<Foo> which has only a getter.

Looked at this function, and it this code:

  let objDescriptor = getDescriptor(obj, accessName)
  let proto = Object.getPrototypeOf(obj)
  let protoDescriptor = proto && getDescriptor(proto, accessName)
  let originalDescriptor = objDescriptor || protoDescriptor

  assert(
    originalDescriptor || accessName in obj,
    `${String(accessName)} does not exist`
  )

originalDescriptor will be undefined but accessName in obj is true.

Works good if I do const a = new A() instead, but this is not the point.

Solution

I've investigated it, and saw that the problem is within https://github.com/tinylibs/tinyspy
I've opened an issue there tinylibs/tinyspy#49 and suggested a fix: tinylibs/tinyspy#50
But the team is probably busy with more urgent stuff.

Reproduction

Check PR tinylibs/tinyspy#50 in https://github.com/tinylibs/tinyspy it has a test that will fail.

Also this: https://stackblitz.com/edit/vitest-dev-vitest-qxyq6eqp?file=src%2Fbasic.ts

System Info

System:
    OS: macOS 15.4
    CPU: (10) arm64 Apple M1 Pro
    Memory: 3.45 GB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.14.0 - ~/.nvm/versions/node/v22.14.0/bin/node
    npm: 10.9.2 - ~/.nvm/versions/node/v22.14.0/bin/npm
    pnpm: 10.7.1 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 135.0.7049.41
    Safari: 18.4
  npmPackages:
    vite: ^6.2.4 => 6.2.4 
    vitest: ^3.1.1 => 3.1.1

Used Package Manager

npm

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    p3-minor-bugAn edge case that only affects very specific usage (priority)upstream

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions