{"id":"bcf74920ac94c12a","repo":"jestjs/jest","slug":"cannot-replace-the-propertykey-property-becau-bcf749","errorCode":null,"errorMessage":"Cannot replace the `${propertyKey}` property because it is a function. Use `jest.spyOn(object, '${propertyKey}')` instead.","messagePattern":"Cannot replace the `(.+?)` property because it is a function\\. Use `jest\\.spyOn\\(object, '(.+?)'\\)` instead\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/jest-mock/src/index.ts","lineNumber":1510,"sourceCode":"          propertyKey,\n        )}\\` property because it has a getter. Use \\`jest.spyOn(object, '${String(\n          propertyKey,\n        )}', 'get').mockReturnValue(value)\\` instead.`,\n      );\n    }\n\n    if (descriptor.set !== undefined) {\n      throw new Error(\n        `Cannot replace the \\`${String(\n          propertyKey,\n        )}\\` property because it has a setter. Use \\`jest.spyOn(object, '${String(\n          propertyKey,\n        )}', 'set').mockReturnValue(value)\\` instead.`,\n      );\n    }\n\n    if (typeof descriptor.value === 'function') {\n      throw new TypeError(\n        `Cannot replace the \\`${String(\n          propertyKey,\n        )}\\` property because it is a function. Use \\`jest.spyOn(object, '${String(\n          propertyKey,\n        )}')\\` instead.`,\n      );\n    }\n\n    const existingRestore = this._findReplacedProperty(object, propertyKey);\n\n    if (existingRestore) {\n      return existingRestore.replaced.replaceValue(value);\n    }\n\n    const isPropertyOwner = Object.prototype.hasOwnProperty.call(\n      object,\n      propertyKey,\n    );","sourceCodeStart":1492,"sourceCodeEnd":1528,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-mock/src/index.ts#L1492-L1528","documentation":"Thrown as a TypeError by jest.replaceProperty when descriptor.value is a function. Replacing a method with a constant value loses the function contract and breaks callers; the correct tool is spyOn, which wraps the function so calls are recorded and a mock implementation can be supplied. The message tells you to use jest.spyOn(object, 'key') instead.","triggerScenarios":"jest.replaceProperty(api, 'fetch', () => {}) where api.fetch is a function; replacing any method with a non-function value; confusing replaceProperty (for data) with spyOn (for methods).","commonSituations":"Copy-pasting a replaceProperty call where a method needed spying; refactor that turned a data property into a method without updating tests.","solutions":["Switch to jest.spyOn(object, 'key').mockImplementation(fn) or mockResolvedValue for async.","If you genuinely need to replace the function entirely with a fresh mock, use jest.spyOn(...).mockReturnValue(...) or assign via spyOn and mockImplementation."],"exampleFix":"// before\njest.replaceProperty(api, 'fetch', mockFetch); // api.fetch is a function\n// after\njest.spyOn(api, 'fetch').mockImplementation(mockFetch);","handlingStrategy":"type-guard","validationCode":"const d = Object.getOwnPropertyDescriptor(obj, key) ?? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), key);\nif (d && typeof d.value === 'function') {\n  jest.spyOn(obj, key).mockImplementation(newValue);\n} else {\n  jest.replaceProperty(obj, key, newValue);\n}","typeGuard":"const isMethodValue = (o: object, k: PropertyKey) => {\n  let d = Object.getOwnPropertyDescriptor(o, k);\n  let p = Object.getPrototypeOf(o);\n  while (!d && p) { d = Object.getOwnPropertyDescriptor(p, k); p = Object.getPrototypeOf(p); }\n  return !!(d && typeof d.value === 'function');\n};\n\nif (isMethodValue(obj, key)) {\n  jest.spyOn(obj, key);\n} else {\n  jest.replaceProperty(obj, key, value);\n}","tryCatchPattern":null,"preventionTips":["Use spyOn for functions, replaceProperty for data values.","After refactoring a data property into a method (or vice versa), update the test's API choice.","Inspect typeof descriptor.value before choosing the API."],"tags":["jest-mock","replaceproperty","spyon","type-error"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}