jestjs/jest · error · Error
${RECEIVED_COLOR('received')} value must be a mock function
Error message
${RECEIVED_COLOR('received')} value must be a mock function What it means
Thrown by `ensureMock` (spyMatchers.ts:1288), used by toHaveReturned, toHaveReturnedTimes, toHaveReturnedWith, toHaveLastReturnedWith, and toHaveNthReturnedWith. It fires when the received value is a Jest mock (`_isMockFunction === true`) is false. These return-value matchers need `received.mock.results`, which only Jest mocks expose — a Jasmine spy (which has `.calls` but no `.mock.results`) is also rejected, hence a stricter guard than ensureMockOrSpy.
Source
Thrown at packages/expect/src/spyMatchers.ts:1289
if (!isMock(received) && !isSpy(received)) {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, expectedArgument, options),
`${RECEIVED_COLOR('received')} value must be a mock or spy function`,
printWithType('Received', received, printReceived),
),
);
}
};
const ensureMock = (
received: any,
matcherName: string,
expectedArgument: string,
options: MatcherHintOptions,
) => {
if (!isMock(received)) {
throw new Error(
matcherErrorMessage(
matcherHint(matcherName, undefined, expectedArgument, options),
`${RECEIVED_COLOR('received')} value must be a mock function`,
printWithType('Received', received, printReceived),
),
);
}
};
export default spyMatchers;
View on GitHub (pinned to 8e6d128e4a)
Solutions
- Use jest.fn() so the function has a .mock.results array: const fn = jest.fn().
- If you only have a spy and need call-count semantics, use toHaveBeenCalledWith (which accepts spies) instead of the toHaveReturned family.
- Confirm the reference passed to expect() is the jest.fn() itself, not a wrapper or the original.
- Ensure module isolation so the mock attaches where the code actually calls it.
Example fix
// before
const fn = jasmine.createSpy('fn'); // or a plain fn
fn();
expect(fn).toHaveReturnedWith(undefined); // not a jest mock
// after
const fn = jest.fn();
fn();
expect(fn).toHaveReturnedWith(undefined);
// if you must use a spy, use call-based matchers
expect(fn).toHaveBeenCalled(); Defensive patterns
Strategy: type-guard
Validate before calling
const fn = received;
if (!(fn != null && fn._isMockFunction === true)) {
throw new Error('return matchers require a jest.fn() (not a plain fn or jasmine spy)');
}
expect(fn).toHaveReturnedWith(value); Type guard
const isJestMock = (v: unknown): boolean => v != null && (v as any)._isMockFunction === true;
Prevention
- Use jest.fn() for any assertion in the toHaveReturned family.
- If you only have a spy, use toHaveBeenCalledWith instead.
- Keep the mock reference, not the original function, when asserting.
When it happens
Trigger: Calling `expect(fn).toHaveReturnedWith(value)` where fn is a plain function, a Jasmine spy (has .calls but not .mock), undefined, or any non-Jest-mock value.
Common situations: Using a Jasmine-style spy (e.g. from an older/jasmine-jquery setup) and expecting Jest return semantics; forgot jest.fn(); passing the original function instead of the mock; the mock was lost after a re-import.
Related errors
- ${RECEIVED_COLOR('received')} value must be a mock or spy fu
- ${EXPECTED_COLOR('expected')} value must be a number
- ${RECEIVED_COLOR('received')} value must be a number
- ${EXPECTED_COLOR('expected')} value must be a function
- ${RECEIVED_COLOR('received')} value must not be null nor und
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/973c527dc63d3130.
Report an issue: GitHub.