Skip to content

fix: ensure sequential mock/unmock resolution#9830

Merged
sheremet-va merged 10 commits intovitest-dev:mainfrom
hi-ogawa:03-09-fix_ensure_sequential_mock_unmock_resolution
Mar 24, 2026
Merged

fix: ensure sequential mock/unmock resolution#9830
sheremet-va merged 10 commits intovitest-dev:mainfrom
hi-ogawa:03-09-fix_ensure_sequential_mock_unmock_resolution

Conversation

@hi-ogawa
Copy link
Collaborator

@hi-ogawa hi-ogawa commented Mar 9, 2026

Description

Resolves https://discord.com/channels/804011606160703521/1480463846253662218/1480481214170402993

Using Promise.all for handling mock and unmock in parallel can cause race condition when multiple mock and unmock of same modules are involved.

The above CI failures is related because it goes through

  • "first import"
    • beforeEach -> doMock
    • test -> import
    • afterEach -> doUnmock
  • "second import"
    • beforeEach -> doMock
    • test -> import
      • 👈 At this step, unmock/mock requests are handled in parallel. If doUnmock processed slower, then module doesn't get mocked and thus module not found.

beforeEach(() => {
vi.doMock('/data', () => ({
data: {
state: 'STARTED',
},
}))
})
afterEach(() => {
vi.doUnmock('/data')
})
test('first import', async () => {
// @ts-expect-error I know this
const { data } = await import('/data')
data.state = 'STOPPED'
expect(data.state).toBe('STOPPED')
})
test('second import should have been re-mocked', async () => {
// @ts-expect-error I know this
const { data } = await import('/data')
expect(data.state).toBe('STARTED')
})

  ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
   FAIL   threads  test/unmock-import.test.ts:23:1 > second import should have been re-mocked
  Error: Cannot find module '/data'
    test/unmock-import.test.ts:25:20
       23| test('second import should have been re-mocked', async () => {
       24|   // @ts-expect-error I know this
       25|   const { data } = await import('/data')
         |                    ^
       26|   expect(data.state).toBe('STARTED')
       27| })
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Run the tests with pnpm test:ci.

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

@hi-ogawa hi-ogawa marked this pull request as ready for review March 9, 2026 13:44
@sheremet-va
Copy link
Member

Could we still have it in parallel if all of them are of the same type? (mock/unmock) I feel like this can hit performance hard otherwise.

@netlify
Copy link

netlify bot commented Mar 10, 2026

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit c28db7d
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/69c206802a4f1a0008f4bc71
😎 Deploy Preview https://deploy-preview-9830--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@hi-ogawa
Copy link
Collaborator Author

That optimization should work fine. Just Claude pushed weird code, so don't look that yet 🙃

Resolve mock/unmock operations in parallel when all pending operations
are of the same type. Fall back to sequential resolution when there's
a mix to preserve ordering correctness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hi-ogawa hi-ogawa force-pushed the 03-09-fix_ensure_sequential_mock_unmock_resolution branch from 253625b to ff15658 Compare March 10, 2026 10:28
@hi-ogawa hi-ogawa requested a review from sheremet-va March 11, 2026 01:40
hi-ogawa and others added 3 commits March 24, 2026 12:31
…lution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… sequential

Group consecutive pending mocks by action type (mock/unmock) and resolve
each group in parallel, while running groups sequentially. This avoids
unnecessarily serializing all resolutions when a single unmock appears
among many mocks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sheremet-va sheremet-va merged commit 7c06598 into vitest-dev:main Mar 24, 2026
13 of 16 checks passed
@hi-ogawa hi-ogawa deleted the 03-09-fix_ensure_sequential_mock_unmock_resolution branch March 24, 2026 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants