Skip to content

Cannot redefine property: mock #8519

@blake-newman

Description

@blake-newman

Describe the bug

Latest beta v4.0.0-beta.9 fails when mocking an already existing mock. As defined as non writable property and this property already exists on the module.

Object.defineProperty(mock, 'mock', {
      configurable: false,
      enumerable: true,
      writable: false,
      value: state
    });

If an existing mock is being re-mocked in a subsequent test without vi.restoreAllMocks() it should not fail (IMO).

If the mock property already exists it should not be set, and return the original mock instance.

I believe the check for is mock function is not working in SSR environment.

Changing the check within spyOn to resolves the issue:

  const mockFn = ssr && original ? original() : original
  if (isMockFunction(mockFn)) {
    return mockFn
  }

Reproduction

import * as module from '../module'

test('a', () => {
  vi.spyOn(module, 'example').mockImplementation(() => {})
})

test('b', () => {
  // TypeError: Cannot redefine property: mock
  vi.spyOn(module, 'example').mockImplementation(() => {})
})

System Info

System:
    OS: macOS 15.6
    CPU: (14) arm64 Apple M4 Pro
    Memory: 4.45 GB / 48.00 GB
    Shell: 5.9 - /opt/homebrew/bin/zsh
  Binaries:
    Node: 22.14.0 - ~/.local/share/mise/installs/node/22.14.0/bin/node
    npm: 11.3.0 - ~/.local/share/mise/installs/node/22.14.0/bin/npm
    pnpm: 10.15.0 - ~/.local/share/mise/installs/node/22.14.0/bin/pnpm
  Browsers:
    Chrome: 139.0.7258.155
    Safari: 18.6
  npmPackages:
    @vitejs/plugin-legacy: 7.2.1 => 7.2.1 
    @vitejs/plugin-vue: 6.0.1 => 6.0.1 
    @vitejs/plugin-vue-jsx: 5.1.1 => 5.1.1 
    @vitest/coverage-istanbul: 4.0.0-beta.9 => 4.0.0-beta.9 
    @vitest/coverage-v8: 4.0.0-beta.9 => 4.0.0-beta.9 
    @vitest/ui: 4.0.0-beta.9 => 4.0.0-beta.9 
    vite: 7.1.3 => 7.1.3 
    vitest: 4.0.0-beta.9 => 4.0.0-beta.9

Used Package Manager

pnpm

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    Projects

    Status

    Approved

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions