vitest vi.mock() hoisting not working: how to fix
Fixes Vitest vi.mock() calls that are not hoisted. Use when the mock is ignored or the real module loads. Not for vi.stubGlobal or vi.spyOn.
TL;DR
vi.mock is hoisted only at the top level of the test file; referencing outer variables inside the factory breaks it. Use the factory form at the top level and vi.hoisted() for any shared values the factory needs.
The query
vitest vi.mock() hoisting not working: how to fixUse this when
- vi.mock is silently ignored
- the real module loads despite the mock
- the factory throws on outer variables
Not for
- vi.spyOn
- vi.stubGlobal
- manual mocks in mocks directories
Steps
- Move the vi.mock() call to the top level of the file, before imports that use the mocked module. Expected output: the mock call sits at file top level.
- If the factory references variables from the file scope, wrap them with vi.hoisted(). Expected output: shared values created inside vi.hoisted().
- Prefer the factory form vi.mock('path', function () { return { mocked: true }; }) so the mock does not depend on import order. Expected output: an explicit factory returning the mock shape.
- Check for a second vi.mock of the same path that overrides the first. Expected output: exactly one mock per module path.
- Re-run and assert the mocked module is the one under test. Expected output: the test observes the mock, not the real module.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_P0qRKpGd7yl5CsKhIPcXaQ
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.