{"id":"fe0038d119827144","repo":"vitest-dev/vitest","slug":"formatreturns-spy-results-msg-value","errorCode":null,"errorMessage":"${formatReturns(spy, results, msg, value)}","messagePattern":"\\$\\{formatReturns\\(spy, results, msg, value\\)\\}","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"packages/expect/src/jest-expect.ts","lineNumber":967,"sourceCode":"    ] satisfies ReturnMatcher<[any]>[]\n  ).forEach(({ name, condition, action }) => {\n    def(name, function (value: any) {\n      const spy = getSpy(this)\n      const pass = condition(spy, value)\n      const isNot = utils.flag(this, 'negate') as boolean\n\n      if ((pass && isNot) || (!pass && !isNot)) {\n        const spyName = spy.getMockName()\n        const msg = utils.getMessage(this, [\n          pass,\n          `expected \"${spyName}\" to ${action} with: #{exp} at least once`,\n          `expected \"${spyName}\" to not ${action} with: #{exp}`,\n          value,\n        ])\n\n        const results\n          = action === 'return' ? spy.mock.results : spy.mock.settledResults\n        throw new AssertionError(formatReturns(spy, results, msg, value))\n      }\n    })\n  });\n  (\n    [\n      {\n        name: 'toHaveLastResolvedWith',\n        condition: (spy, value) => {\n          const result\n            = spy.mock.settledResults.at(-1)\n          return Boolean(\n            result\n            && result.type === 'fulfilled'\n            && jestEquals(result.value, value),\n          )\n        },\n        action: 'resolve',\n      },","sourceCodeStart":949,"sourceCodeEnd":985,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/expect/src/jest-expect.ts#L949-L985","documentation":"AssertionError thrown by toHaveResolvedWith/toHaveReturnedWith/toReturnWith when the spy never produced a matching return/resolved value (positive) or did produce one under .not. The message is enriched by formatReturns, which diffs each recorded result against the expected value.","triggerScenarios":"expect(spy).toHaveReturnedWith(value) where no entry in spy.mock.results (type==='return') matches; or expect(spy).toHaveResolvedWith(value) where no settledResults entry (type==='fulfilled') matches. Condition (pass && isNot) || (!pass && !isNot) controls the throw.","commonSituations":"Asserting on a mock's return value when the mock threw instead of returned, when it resolved with a different shape, or when it was never invoked. Also common when the wrong result list is consulted (returns vs settled for async).","solutions":["Inspect spy.mock.results / spy.mock.settledResults in a debug step to see what was actually returned.","Use expect.any / expect.objectContaining to relax the expected shape.","Ensure the mock actually executed the path that returns — a thrown call has type 'throw' and will not match a 'return' assertion."],"exampleFix":"// before\nexpect(api.fetch).toHaveReturnedWith({ id: 1 });\n// after\nexpect(api.fetch).toHaveResolvedWith(expect.objectContaining({ id: 1 }));","handlingStrategy":"validation","validationCode":"const returns = spy.mock.results;\nif (!returns.some(r => r.type === 'return' && jestEquals(r.value, expected))) {\n  console.warn('no matching return; results:', returns);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Inspect spy.mock.results / spy.mock.settledResults before asserting.","Use toHaveResolvedWith for async mocks (settledResults) and toHaveReturnedWith for sync (results)."],"tags":["assertion","mock","spy","tohavereturnedwith","tohaveresolvedwith","diff"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}