{"id":"69d4e960a783ce2f","repo":"jestjs/jest","slug":"received-value-must-be-a-mock-function","errorCode":null,"errorMessage":"received value must be a mock function","messagePattern":"received value must be a mock function","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/expect/src/spyMatchers.ts","lineNumber":1289,"sourceCode":"  if (!isMock(received) && !isSpy(received)) {\n    throw new Error(\n      matcherErrorMessage(\n        matcherHint(matcherName, undefined, expectedArgument, options),\n        `${RECEIVED_COLOR('received')} value must be a mock or spy function`,\n        printWithType('Received', received, printReceived),\n      ),\n    );\n  }\n};\n\nconst ensureMock = (\n  received: any,\n  matcherName: string,\n  expectedArgument: string,\n  options: MatcherHintOptions,\n) => {\n  if (!isMock(received)) {\n    throw new Error(\n      matcherErrorMessage(\n        matcherHint(matcherName, undefined, expectedArgument, options),\n        `${RECEIVED_COLOR('received')} value must be a mock function`,\n        printWithType('Received', received, printReceived),\n      ),\n    );\n  }\n};\n\nexport default spyMatchers;\n","sourceCodeStart":1271,"sourceCodeEnd":1300,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/expect/src/spyMatchers.ts#L1271-L1300","documentation":"Thrown by `ensureMock` (spyMatchers.ts:1282), invoked from `toHaveReturned`, `toHaveReturnedTimes`, `toHaveReturnedWith`, `toHaveLastReturnedWith`, and `toHaveNthReturnedWith`. It fires when the received value is not a Jest mock function (`_isMockFunction === true`). These matchers specifically need `received.mock.results` (return values), which only Jest mocks carry — a Jasmine spy exposes `.calls` but not `.mock.results`, so `ensureMock` is stricter than `ensureMockOrSpy`.","triggerScenarios":"Calling `expect(plainFn).toHaveReturnedWith(value)` on a non-mock function; `expect(spy).toHaveReturned()` where `spy` is a Jasmine-style spy without a `.mock` property; `expect(obj.method).toHaveReturned()` on an unspied method; using a non-Jest fake (sinon stub, vitest spy) that doesn't expose `_isMockFunction`.","commonSituations":"Spying with a library other than Jest; forgetting `jest.fn()` around a callback; the function under test is the real implementation; using `toHaveReturned*` on something that was set up with `jest.spyOn` but where the return-tracking mock shape is missing (rare — `jest.spyOn` does produce a mock).","solutions":["Use `jest.fn()` to create the mock so `.mock.results` is populated.","If you only need call assertions (not return values), switch to `toHaveBeenCalled*` matchers which accept spies too.","Log `received._isMockFunction` — must be `true` for `toHaveReturned*`.","Ensure you are not passing a different framework's spy (sinon/vitest)."],"exampleFix":"// before\nconst fn = sinon.fake(); // not a Jest mock\nrun(fn);\nexpect(fn).toHaveReturnedWith('ok');\n\n// after\nconst fn = jest.fn();\nrun(fn);\nexpect(fn).toHaveReturnedWith('ok');","handlingStrategy":"type-guard","validationCode":"if (received == null || received._isMockFunction !== true) {\n  throw new Error('received must be a jest.fn() mock (spies without .mock.results are not supported here)');\n}\nexpect(received).toHaveReturned();","typeGuard":"const isJestMock = (v: unknown): v is {mock: {results: Array<unknown>; calls: Array<unknown>}; getMockName: () => string} =>\n  v != null && (v as any)._isMockFunction === true;","tryCatchPattern":"try {\n  expect(received).toHaveReturnedWith(value);\n} catch (e) {\n  if (e instanceof Error && /must be a mock function/.test(e.message)) {\n    console.error('received is not a jest.fn() mock:', received);\n  }\n  throw e;\n}","preventionTips":["Use `jest.fn()` so `.mock.results` is populated for return assertions.","For spies or non-Jest fakes, switch to `toHaveBeenCalled*` matchers.","Confirm `received._isMockFunction === true` before `toHaveReturned*` calls."],"tags":["jest","expect","mock","spy","assertion","configuration"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}