jestjs/jest · error · Error
Attempting to import a mock without a factory
Error message
Attempting to import a mock without a factory
What it means
Thrown by EsmLoader.importMock when an ESM import resolves to a mocked module but no factory was registered for it via `jest.unstable_mockModule`. The async ESM mocking path requires a factory to synthesize the mock module; without one Jest cannot construct it.
Source
Thrown at packages/jest-runtime/src/internals/EsmLoader.ts:1324
private async importMock<T = unknown>(
moduleName: string,
moduleID: string,
context: VMContext,
): Promise<T> {
if (this.registries.hasModuleMock(moduleID)) {
return this.registries.getModuleMock(moduleID) as T;
}
const factory = this.mockState.getEsmFactory(moduleID);
if (factory) {
const invokedFactory = (await factory()) as Record<string, unknown>;
const module = syntheticFromExports(moduleName, context, invokedFactory);
this.registries.setModuleMock(moduleID, module);
return evaluateSyntheticModule(module) as T;
}
throw new Error('Attempting to import a mock without a factory');
}
private async importWasmModule(
source: BufferSource,
identifier: string,
context: VMContext,
): Promise<SyntheticModule> {
// Use async `WebAssembly.compile` (rather than the sync constructor used
// by the v24.9+ sync core) to avoid blocking the event loop on large wasm
// modules in the legacy async path.
const wasmModule = await WebAssembly.compile(source);
const moduleLookup: Record<string, VMModule> = {};
for (const {module} of WebAssembly.Module.imports(wasmModule)) {
if (moduleLookup[module] === undefined) {
const resolvedModule = await this.resolveModule<VMModule>(
module,
identifier,
context,View on GitHub (pinned to f49721c78e)
Solutions
- Use `jest.unstable_mockModule('x', () => ({ ... }))` with an explicit factory function returning the mock namespace.
- Do not call the CJS `jest.mock('x')` (without factory) for modules imported as ESM; ESM automocking is unsupported.
- Ensure the factory is registered before the import: call `unstable_mockModule` in setupFilesAfterEach or at the top of the test before the dynamic `import()`.
- If you need to unmock, call `jest.unstable_unmockModule('x')` rather than leaving a stub without a factory.
Example fix
// before
jest.mock('my-esm-module'); // CJS automock, no factory
import('my-esm-module'); // throws
// after
jest.unstable_mockModule('my-esm-module', () => ({
doThing: () => 'mocked',
}));
await import('my-esm-module'); Defensive patterns
Strategy: validation
Validate before calling
// Before importing an ESM module you intend to mock, ensure a factory is registered
function mockEsm(name, factory) {
if (typeof factory !== 'function') {
throw new Error(`unstable_mockModule('${name}') needs a factory function`);
}
jest.unstable_mockModule(name, factory);
} Prevention
- Always pass a factory to `jest.unstable_mockModule` — never use bare `jest.mock` for ESM.
- Register the mock factory before the dynamic `import()` of the target module.
- Do not mix CJS `jest.mock` automocking with ESM imports of the same module.
When it happens
Trigger: Calling `jest.mock('x')` (CJS-style, no factory) on a module that is later imported as ESM, or calling `jest.unstable_mockModule('x')` without a factory argument. The ESM loader looks up `mockState.getEsmFactory(moduleID)`, finds nothing, and throws.
Common situations: Mixing CJS `jest.mock` automocking with ESM imports (automocking is not supported for ESM — you must provide an explicit factory); forgetting the second argument to `unstable_mockModule`; a setup file calling `jest.mock` for a module that the test imports via ESM.
Related errors
- `unstable_mockModule` must be passed a mock factory
- jest.config.mts requires native TypeScript support. Ensure y
- Unable to load resolver at ${options.resolver}
- Invalid data URI
- Missing data URI encoding
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/24ee3ebb283de168.json.
Report an issue: GitHub.