vitest-dev / vitest-dev/vitest

When using vi.mock() with In-Source Testing, mockReturnValue doesn't work

Open
#8,653 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

p3-minor-bug
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.mock twice (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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.