vitest-dev / vitest-dev/vitest
When using vi.mock() with In-Source Testing, mockReturnValue doesn't work
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 17.1k
- Forks
- 2k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 94
Description
Describe the bug
project structure
My project structure is below:
(See also the repro link on stackblitz)
.
├── src
│ ├── a.ts
│ ├── main_a.ts
│ ├── main_b.ts
│ └── x.ts
└── vite.config.ts
graph LR;
MA((main_a.ts))--import-->A((a.ts))
MA((main_a.ts))--import-->MB((main_b.ts))
A--import-->X((x.ts))
MB--import-->X
The problem I'm experiencing
I'm using vi.mock() in In-Source Testing.
I want to use mockReturnValue() on a module that has been vi.mock()ed, but I can't mock the function implementation.
// main_a.ts
if (import.meta.vitest) {
const { describe, it, expect, vi } = import.meta.vitest;
vi.mock('./x.ts', () => ({
getName: vi.fn(() => '[[mocked from a]]'),
}));
describe('run', () => {
it('enable mock', () => {
vi.mocked(getName).mockReturnValue('[[mocked in test]]');
const res = run();
// If mocking is enabled, `[[mocked in test]]` should be returned.
// but it returns `[[mocked from a]]`.
expect(res).toBe('hi, [[mocked in test]]');
});
});
}
FAIL node src/main_a.ts > run > enable mock
AssertionError: expected 'hi, [[mocked from a]]' to be 'hi, [[mocked in test]]' // Object.is equality
Expected: "hi, [[mocked in test]]"
Received: "hi, [[mocked from a]]"
The above result shows that mockReturnValue() is not working.
As far as I've tried, this seems to occur under the following conditions:
- In-source testing
- Calling
vi.mocktwice (in both main_a.ts and main_b.ts)
One odd thing I've come across is that if I change the filename from a.ts to z.ts the test passes. Why does the test result change depending on the filename? Is this expected behavior?
Reproduction
https://stackblitz.com/edit/vitest-dev-vitest-g93bquev?file=src%2Fmain_a.ts
System Info
System:
OS: macOS 15.5
CPU: (8) arm64 Apple M1 Pro
Memory: 110.41 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.1.0 - ~/.anyenv/envs/nodenv/versions/24.1.0/bin/node
npm: 11.3.0 - ~/.anyenv/envs/nodenv/versions/24.1.0/bin/npm
Deno: 2.3.6 - ~/.deno/bin/deno
Browsers:
Chrome: 140.0.7339.214
Chrome Canary: 143.0.7445.0
Safari: 18.5
npmPackages:
vite: ^7.0.5 => 7.0.5
vitest: ^4.0.0-beta.15 => 4.0.0-beta.15
Note: Same behavior with vite@3 .
Used 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the StackBlitz reproduction with src/main_a.ts, src/main_b.ts, a.ts, x.ts, and vite.config.ts, then compare the result after renaming a.ts to z.ts. Trace the two in-source vi.mock() calls and the mockReturnValue() assertion. Done means the test returns 'hi, [[mocked in test]]' and the filename-dependent behavior is covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript, vite
- Domain
- testing-qa, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100