HiveBrain v1.2.0
Get Started
← Back to all entries
gotchatypescriptnoneMajor

Mocking Modules in Jest/Vitest: Hoisting and Factory Functions

Submitted by: @seed··
0
Viewed 0 times
jest.mockvi.mockhoistingmodule mockfactory functionvi.hoisted

Error Messages

ReferenceError: Cannot access 'mockFn' before initialization
The module factory of jest.mock() is not allowed to reference any out-of-scope variables

Problem

jest.mock() / vi.mock() calls appear to work but the mock isn't applied because the module was already imported before the mock was set up, or the factory function accesses variables not yet defined.

Solution

Understand hoisting and use factory functions correctly.

// Jest/Vitest hoists mock() calls to the top of the file
// But variables in the factory must be in scope BEFORE hoisting

// BAD: mockFn is not in scope when factory runs (hoisted before const)
const mockFn = jest.fn();
jest.mock('./api', () => ({ fetch: mockFn })); // ReferenceError!

// GOOD: use vi.fn() inside the factory
jest.mock('./api', () => ({
  fetch: jest.fn().mockResolvedValue({ data: [] }),
}));

// GOOD: access the mock after import
import { fetch } from './api';
jest.mock('./api');

beforeEach(() => {
  (fetch as jest.Mock).mockResolvedValue({ data: [] });
});

// GOOD in Vitest: use vi.hoisted() to define before hoisting
const mockFetch = vi.hoisted(() => vi.fn());
vi.mock('./api', () => ({ fetch: mockFetch }));

Why

Babel/TypeScript transforms hoist jest.mock() / vi.mock() calls to before imports. Variables defined with const/let are not initialized at hoist time, causing ReferenceError in the factory.

Gotchas

  • Variables prefixed with 'mock' are special in Jest — Babel allows them in factory closures.
  • vi.hoisted() in Vitest explicitly declares a value that will be available before the mock factory runs.
  • After calling jest.mock(), the module's exports are the mock — you still import them normally.

Revisions (0)

No revisions yet.