Vitest vi.mock factory hoisting ReferenceError in CI
Vitest hoists vi.mock to the top of the file, above your imports and variable declarations. If the mock factory closes over an outer variable, that variable is not initialized yet when the factory runs, so it throws.
What this error means
A test fails at load with "ReferenceError: Cannot access 'X' before initialization" pointing at a vi.mock factory that references a const or import declared lower in the file.
ReferenceError: Cannot access 'mockFn' before initialization
❯ src/service.test.ts:3:24
2| const mockFn = vi.fn();
3| vi.mock('./api', () => ({ fetchUser: mockFn }));
| ^Common causes
The factory references a hoisted-over variable
Because vi.mock is moved above the file body, any outer const/import it uses is in the temporal dead zone when the factory executes.
A top-level mock value not wrapped in vi.hoisted
Values the factory needs were declared normally instead of through vi.hoisted, so they are not available at hoist time.
How to fix it
Declare shared values with vi.hoisted
- Wrap variables the factory needs in
vi.hoistedso they are initialized before the mock runs. - Reference the hoisted object from inside the factory.
- Re-run so the mock initializes cleanly.
const { mockFn } = vi.hoisted(() => ({ mockFn: vi.fn() }));
vi.mock('./api', () => ({ fetchUser: mockFn }));Or define the mock inline
If the factory needs no outer reference, define everything inside it so nothing is hoisted over.
vi.mock('./api', () => ({ fetchUser: vi.fn() }));How to prevent it
- Use
vi.hoistedfor any value a mock factory must reference. - Keep mock factories self-contained where possible.
- Remember
vi.mockruns before the rest of the module body.