From 3cbbb17f1eefd5c9d7d388be7e07c41a95dce21a Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 26 Feb 2026 17:54:11 +0900 Subject: [PATCH] fix: fix re-mocking virtual module (#9748) --- .../moduleRunner/startVitestModuleRunner.ts | 4 +- test/core/test/do-mock-reset-modules.test.ts | 70 +++++++++++++++++++ test/core/test/fixtures/increment-indirect.ts | 5 ++ .../test/fixtures/virtual-module-indirect.ts | 6 ++ test/core/vite.config.ts | 12 +++- 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 test/core/test/do-mock-reset-modules.test.ts create mode 100644 test/core/test/fixtures/increment-indirect.ts create mode 100644 test/core/test/fixtures/virtual-module-indirect.ts diff --git a/packages/vitest/src/runtime/moduleRunner/startVitestModuleRunner.ts b/packages/vitest/src/runtime/moduleRunner/startVitestModuleRunner.ts index 898be8307..6a818d2ee 100644 --- a/packages/vitest/src/runtime/moduleRunner/startVitestModuleRunner.ts +++ b/packages/vitest/src/runtime/moduleRunner/startVitestModuleRunner.ts @@ -108,8 +108,8 @@ export function startVitestModuleRunner(options: ContextModuleRunnerOptions): Vi return { code: '', file: null, - id, - url: id, + id: resolvedMock.id, + url: resolvedMock.url, invalidate: false, mockedModule: resolvedMock, } diff --git a/test/core/test/do-mock-reset-modules.test.ts b/test/core/test/do-mock-reset-modules.test.ts new file mode 100644 index 000000000..1d6425ad8 --- /dev/null +++ b/test/core/test/do-mock-reset-modules.test.ts @@ -0,0 +1,70 @@ +import { expect, test, vi } from 'vitest' + +test('multiple resetModules and doMock for indirect actual module', async () => { + vi.doUnmock('./fixtures/increment') + + const { incrementIndirect: originalIncrement } = await import('./fixtures/increment-indirect') + expect(originalIncrement(1)).toBe(2) + + vi.doMock('./fixtures/increment', () => ({ + increment: (num: number) => num + 10, + })) + vi.resetModules() + + const { incrementIndirect: incrementWith10 } = await import('./fixtures/increment-indirect') + expect(incrementWith10(1)).toBe(11) + + vi.doMock('./fixtures/increment', () => ({ + increment: (num: number) => num + 20, + })) + vi.resetModules() + + const { incrementIndirect: incrementWith20 } = await import('./fixtures/increment-indirect') + expect(incrementWith20(1)).toBe(21) + + vi.doMock('./fixtures/increment', () => ({ + increment: (num: number) => num + 30, + })) + + const { incrementIndirect: incrementWith20Still } = await import('./fixtures/increment-indirect') + expect(incrementWith20Still(1)).toBe(21) +}) + +test('multiple doMock for direct virtual module', async () => { + // @ts-expect-error virtual module + const { value: originalValue } = await import('virtual-module-direct') + expect(originalValue).toBe('original-direct') + + vi.doMock('virtual-module-direct', () => ({ + value: 'direct-1', + })) + + // @ts-expect-error virtual module + const { value: mockedValue1 } = await import('virtual-module-direct') + expect(mockedValue1).toBe('direct-1') + + vi.doMock('virtual-module-direct', () => ({ + value: 'direct-2', + })) + + // @ts-expect-error virtual module + const { value: mockedValue2 } = await import('virtual-module-direct') + expect(mockedValue2).toBe('direct-2') +}) + +test('multiple resetModules and doMock for indirect virtual module', async () => { + const { getVirtualValue: originalGetVirtualValue } = await import('./fixtures/virtual-module-indirect') + expect(originalGetVirtualValue()).toBe('original-indirect') + + vi.doMock('virtual-module-indirect', () => ({ value: 'indirect-1' })) + vi.resetModules() + + const { getVirtualValue: mockedGetVirtualValue1 } = await import('./fixtures/virtual-module-indirect') + expect(mockedGetVirtualValue1()).toBe('indirect-1') + + vi.resetModules() + vi.doMock('virtual-module-indirect', () => ({ value: 'indirect-2' })) + + const { getVirtualValue: mockedGetVirtualValue2 } = await import('./fixtures/virtual-module-indirect') + expect(mockedGetVirtualValue2()).toBe('indirect-2') +}) diff --git a/test/core/test/fixtures/increment-indirect.ts b/test/core/test/fixtures/increment-indirect.ts new file mode 100644 index 000000000..d7f53ebe0 --- /dev/null +++ b/test/core/test/fixtures/increment-indirect.ts @@ -0,0 +1,5 @@ +import { increment } from './increment' + +export function incrementIndirect(num: number) { + return increment(num) +} diff --git a/test/core/test/fixtures/virtual-module-indirect.ts b/test/core/test/fixtures/virtual-module-indirect.ts new file mode 100644 index 000000000..520939bfd --- /dev/null +++ b/test/core/test/fixtures/virtual-module-indirect.ts @@ -0,0 +1,6 @@ +// @ts-expect-error virtual module +import { value } from 'virtual-module-indirect' + +export function getVirtualValue() { + return value +} diff --git a/test/core/vite.config.ts b/test/core/vite.config.ts index 1a597e614..adbb8a680 100644 --- a/test/core/vite.config.ts +++ b/test/core/vite.config.ts @@ -11,7 +11,7 @@ export default defineConfig({ { name: 'example', resolveId(source) { - if (source === 'virtual-module') { + if (source === 'virtual-module' || source === 'virtual-module-direct' || source === 'virtual-module-indirect') { return source } }, @@ -21,6 +21,16 @@ export default defineConfig({ export const value = 'original'; ` } + if (id === 'virtual-module-direct') { + return ` + export const value = 'original-direct'; + ` + } + if (id === 'virtual-module-indirect') { + return ` + export const value = 'original-indirect'; + ` + } }, }, ], -- 2.51.2