-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Mocked base classes cause overridden methods to also be mocked #8870
Copy link
Copy link
Labels
p3-minor-bugAn edge case that only affects very specific usage (priority)An edge case that only affects very specific usage (priority)
Description
Describe the bug
If a base class is mocked, any subclasses that extend from it will also have all matching methods mocked too. This means there's no way to test the overridden method of a subclass since it will be replaced with a mock of the base class. This is better explained with code below.
This bug seems to have started with v4 and is present in all v4 versions
Reproduction
First a base class and a subclass which overrides the one method, in separate files so the base class can be auto-mocked in isolation:
// foo.ts
export class Foo {
doSomething(): boolean {
return false;
}
}
// bar.ts
import { Foo } from './foo.js';
export class Bar extends Foo {
override doSomething(): boolean {
return true;
}
doSomethingElse(): boolean {
return true;
}
}Then a series of tests. All the doSomething tests fail despite not being explicitly mocked. While the doSomethingElse tests all pass since it does not match the name of a mocked method in the base class:
// bar.spec.ts
import { describe, expect, it, vi } from 'vitest';
import { Bar } from './bar.js';
vi.mock(import('./foo.js'));
describe('Bar', () => {
describe('doSomething', () => {
it('returns true', () => {
const bar = new Bar();
expect(bar.doSomething()).toBe(true);
});
it('should match the prototype', () => {
const bar = new Bar();
expect(bar.doSomething).toBe(Bar.prototype.doSomething);
});
it('should not be mocked', () => {
const bar = new Bar();
expect(bar.doSomething).not.toHaveProperty('mock')
});
});
describe('doSomethingElse', () => {
it('returns true', () => {
const bar = new Bar();
expect(bar.doSomethingElse()).toBe(true);
});
it('should match the prototype', () => {
const bar = new Bar();
expect(bar.doSomethingElse).toBe(Bar.prototype.doSomethingElse);
});
it('should not be mocked', () => {
const bar = new Bar();
expect(bar.doSomethingElse).not.toHaveProperty('mock')
});
});
});System Info
System:
OS: macOS 26.0.1
CPU: (16) arm64 Apple M4 Max
Memory: 1.06 GB / 64.00 GB
Shell: 4.1.2 - /opt/homebrew/bin/fish
Binaries:
Node: 22.18.0 - /Users/matanui159/.local/state/fnm_multishells/12587_1761795789805/bin/node
Yarn: 1.22.22 - /Users/matanui159/.local/state/fnm_multishells/12587_1761795789805/bin/yarn
npm: 10.9.3 - /Users/matanui159/.local/state/fnm_multishells/12587_1761795789805/bin/npm
pnpm: 10.20.0 - /Users/matanui159/.local/state/fnm_multishells/12587_1761795789805/bin/pnpm
Browsers:
Chrome: 141.0.7390.123
Edge: 141.0.3537.99
Safari: 26.0.1
npmPackages:
vitest: ^4.0.5 => 4.0.5Used Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
p3-minor-bugAn edge case that only affects very specific usage (priority)An edge case that only affects very specific usage (priority)
Type
Projects
Status
Approved