From b61d1ced3a11fea09e02a95a8b8fbcecbf0944ac Mon Sep 17 00:00:00 2001 From: Kasper Peulen Date: Wed, 7 Oct 2026 14:34:26 +0200 Subject: [PATCH] fix(browser): wait for setup mocks before importing a test file (#11520) --- packages/browser/src/client/tester/runner.ts | 2 ++ .../mocking-setup-file/browser-setup.ts | 3 ++ .../mocking-setup-file/dynamic-import.test.ts | 6 ++++ .../fixtures/mocking-setup-file/source.ts | 3 ++ .../mocking-setup-file/static-import.test.ts | 6 ++++ .../mocking-setup-file/vitest.config.ts | 28 +++++++++++++++++++ test/browser/specs/mocking.test.ts | 21 ++++++++++++++ 7 files changed, 69 insertions(+) create mode 100644 test/browser/fixtures/mocking-setup-file/browser-setup.ts create mode 100644 test/browser/fixtures/mocking-setup-file/dynamic-import.test.ts create mode 100644 test/browser/fixtures/mocking-setup-file/source.ts create mode 100644 test/browser/fixtures/mocking-setup-file/static-import.test.ts create mode 100644 test/browser/fixtures/mocking-setup-file/vitest.config.ts diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index e41be5a5b..fef76125f 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -343,6 +343,8 @@ function createBrowserRunner( if (mode === 'collect' && trace !== 'off') { await this.commands.triggerCommand('__vitest_startTracing', []) } + // static imports don't wait for mocks queued by a setup file + await mocker.prepare() try { await import(/* @vite-ignore */ importpath) } catch (err) { diff --git a/test/browser/fixtures/mocking-setup-file/browser-setup.ts b/test/browser/fixtures/mocking-setup-file/browser-setup.ts new file mode 100644 index 000000000..e518f3911 --- /dev/null +++ b/test/browser/fixtures/mocking-setup-file/browser-setup.ts @@ -0,0 +1,3 @@ +import { vi } from 'vitest' + +vi.mock('./source', () => ({ answer: () => 'mocked' })) diff --git a/test/browser/fixtures/mocking-setup-file/dynamic-import.test.ts b/test/browser/fixtures/mocking-setup-file/dynamic-import.test.ts new file mode 100644 index 000000000..3a281cb6e --- /dev/null +++ b/test/browser/fixtures/mocking-setup-file/dynamic-import.test.ts @@ -0,0 +1,6 @@ +import { expect, test } from 'vitest' + +test('a dynamic import gets the mock from the setup file', async () => { + const { answer } = await import('./source') + expect(answer()).toBe('mocked') +}) diff --git a/test/browser/fixtures/mocking-setup-file/source.ts b/test/browser/fixtures/mocking-setup-file/source.ts new file mode 100644 index 000000000..2bb943e67 --- /dev/null +++ b/test/browser/fixtures/mocking-setup-file/source.ts @@ -0,0 +1,3 @@ +export function answer() { + return 'original' +} diff --git a/test/browser/fixtures/mocking-setup-file/static-import.test.ts b/test/browser/fixtures/mocking-setup-file/static-import.test.ts new file mode 100644 index 000000000..0cd5adc2b --- /dev/null +++ b/test/browser/fixtures/mocking-setup-file/static-import.test.ts @@ -0,0 +1,6 @@ +import { expect, test } from 'vitest' +import { answer } from './source' + +test('a static import gets the mock from the setup file', () => { + expect(answer()).toBe('mocked') +}) diff --git a/test/browser/fixtures/mocking-setup-file/vitest.config.ts b/test/browser/fixtures/mocking-setup-file/vitest.config.ts new file mode 100644 index 000000000..ac0ac0bd9 --- /dev/null +++ b/test/browser/fixtures/mocking-setup-file/vitest.config.ts @@ -0,0 +1,28 @@ +import { fileURLToPath } from 'node:url' +import { defineConfig } from 'vitest/config' +import { instances, provider } from '../../settings' + +export default defineConfig({ + cacheDir: fileURLToPath(new URL('./node_modules/.vite', import.meta.url)), + plugins: [ + { + // registering the mock takes longer than importing the test file + name: 'slow-mock-registration', + enforce: 'pre', + async resolveId(id, importer) { + if (id === './source' && importer?.endsWith('browser-setup.ts')) { + await new Promise(resolve => setTimeout(resolve, 500)) + } + }, + }, + ], + test: { + setupFiles: ['./browser-setup.ts'], + browser: { + enabled: true, + provider, + instances, + headless: true, + }, + }, +}) diff --git a/test/browser/specs/mocking.test.ts b/test/browser/specs/mocking.test.ts index 62076655a..4c6bbc49c 100644 --- a/test/browser/specs/mocking.test.ts +++ b/test/browser/specs/mocking.test.ts @@ -104,3 +104,24 @@ test('mocking out of root', async () => { expect(vitest.stdout).toReportPassedTest('basic.test.js', browser) }) }) + +// fix https://github.com/vitest-dev/vitest/issues/11519 +test('mocks from a setup file apply to static imports of a test file', async () => { + const result = await runVitest({ + root: 'fixtures/mocking-setup-file', + }) + + onTestFailed(() => { + console.error(result.stdout) + console.error(result.stderr) + }) + + expect(result.stderr).toReportNoErrors() + + instances.forEach(({ browser }) => { + expect(result.stdout).toReportPassedTest('static-import.test.ts', browser) + expect(result.stdout).toReportPassedTest('dynamic-import.test.ts', browser) + }) + + expect(result.exitCode).toBe(0) +}) -- 2.51.2