Skip to content

vi.spyOn + mockRestore leaves prototype method in own properties #7804

@hi-ogawa

Description

@hi-ogawa

Describe the bug

I was reviewing #7801 and I realized we have this behavior. This looks like something a little unexpected in terms of mockRestore. Creating a repro just in case for the record, but it might not be possible to deal with this accurately.

import { test, vi, expect } from 'vitest';

test('repro', () => {
  class Foo {
    f() {
      return 'original';
    }
  }

  // initially there's no own properties
  const foo = new Foo();
  expect(foo.f()).toMatchInlineSnapshot(`"original"`);
  expect(Object.getOwnPropertyDescriptors(foo)).toMatchInlineSnapshot(`{}`);

  // mocked function in own property
  const spy = vi.spyOn(foo, 'f').mockImplementation(() => 'mocked');
  expect(foo.f()).toMatchInlineSnapshot(`"mocked"`);
  expect(Object.getOwnPropertyDescriptors(foo)).toMatchInlineSnapshot(`
    {
      "f": {
        "configurable": true,
        "enumerable": false,
        "value": [MockFunction f] {
          "calls": [
            [],
          ],
          "results": [
            {
              "type": "return",
              "value": "mocked",
            },
          ],
        },
        "writable": true,
      },
    }
  `);

  // probably original prototype method is not moved to own property
  spy.mockRestore();
  expect(foo.f()).toMatchInlineSnapshot(`"original"`);
  expect(Object.getOwnPropertyDescriptors(foo)).toMatchInlineSnapshot(`
    {
      "f": {
        "configurable": true,
        "enumerable": false,
        "value": [Function],
        "writable": true,
      },
    }
  `);
});

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-yrcblgdr?file=test%2Frepro.test.ts

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    @vitest/ui: latest => 3.1.1 
    vite: latest => 6.2.5 
    vitest: latest => 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)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions