jestjs/jest · error · TypeError
Argument passed to callFake should be a function, got
Error message
Argument passed to callFake should be a function, got ${fn} What it means
A spy's `.callFake(fn)` replaces the spy's behavior with the given function. SpyStrategy.callFake validates that `fn` is a function at SpyStrategy.ts:91; if not, it throws a TypeError showing the actual value passed. Passing a non-function would silently break the spy's stub behavior, so jasmine fails fast.
Solutions
- Pass the function reference, not its invocation: `spy.and.callFake(myFn)` (no parentheses).
- If the fake should be async, pass an async function: `spy.and.callFake(async () => {...})`.
- Check that the variable holding the function is defined before passing it.
Example fix
// before spy.and.callFake(realImpl()); // after spy.and.callFake(realImpl);
Defensive patterns
Strategy: type-guard
Validate before calling
// Guard callFake calls with a type check.
function safeCallFake(spy: { and: { callFake: (fn: Function) => unknown } }, fn: unknown) {
if (typeof fn !== 'function') {
throw new TypeError(`callFake requires a function, got ${typeof fn}`);
}
return spy.and.callFake(fn);
} Type guard
function isCallable(value: unknown): value is Function {
return typeof value === 'function';
} Prevention
- Pass the function reference, not its return value: `callFake(fn)` not `callFake(fn())`.
- For async fakes, pass an async arrow function.
- Verify the function variable is defined before passing it.
When it happens
Trigger: Calling `spy.and.callFake('not a function')`, `spy.and.callFake(undefined)`, or `spy.and.callFake({})` where a function was expected. The check `typeof fn !== 'function'` at line 91 triggers the throw at line 92.
Common situations: Passing the return value of a function instead of the function itself (e.g. `callFake(myFn())` instead of `callFake(myFn)`); passing an async value or a promise; a variable that was conditionally assigned and is undefined; refactoring that changed a function reference to an object.
Related errors
- Invalid first argument. It must be a callback function.
- Invalid second argument
- Invalid second argument
- Jasmine spies would overwrite the 'and' and 'calls'…
- any() expects to be passed a constructor function. Please…
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/94db76f62a1e6af4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/jest-jasmine2/src/jasmine/SpyStrategy.ts:92
const values = Array.prototype.slice.call(arguments);
plan = function () {
return values.shift();
};
return getSpy();
};
this.throwError = function (something) {
const error =
something instanceof Error ? something : new Error(something);
plan = function () {
throw error;
};
return getSpy();
};
this.callFake = function (fn) {
if (typeof fn !== 'function') {
throw new TypeError(
`Argument passed to callFake should be a function, got ${fn}`,
);
}
plan = fn;
return getSpy();
};
this.stub = function (_fn) {
plan = function () {};
return getSpy();
};
}
}
View on GitHub (pinned to 8e6d128e4a)