jestjs/jest · error · TypeError
Cannot replace the `${propertyKey}` property because it is a
Error message
Cannot replace the `${propertyKey}` property because it is a function. Use `jest.spyOn(object, '${propertyKey}')` instead. What it means
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.
Source
Thrown at packages/jest-mock/src/index.ts:1510
propertyKey,
)}\` property because it has a getter. Use \`jest.spyOn(object, '${String(
propertyKey,
)}', 'get').mockReturnValue(value)\` instead.`,
);
}
if (descriptor.set !== undefined) {
throw new Error(
`Cannot replace the \`${String(
propertyKey,
)}\` property because it has a setter. Use \`jest.spyOn(object, '${String(
propertyKey,
)}', 'set').mockReturnValue(value)\` instead.`,
);
}
if (typeof descriptor.value === 'function') {
throw new TypeError(
`Cannot replace the \`${String(
propertyKey,
)}\` property because it is a function. Use \`jest.spyOn(object, '${String(
propertyKey,
)}')\` instead.`,
);
}
const existingRestore = this._findReplacedProperty(object, propertyKey);
if (existingRestore) {
return existingRestore.replaced.replaceValue(value);
}
const isPropertyOwner = Object.prototype.hasOwnProperty.call(
object,
propertyKey,
);View on GitHub (pinned to f49721c78e)
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.
Example fix
// before jest.replaceProperty(api, 'fetch', mockFetch); // api.fetch is a function // after jest.spyOn(api, 'fetch').mockImplementation(mockFetch);
Defensive patterns
Strategy: type-guard
Validate before calling
const d = Object.getOwnPropertyDescriptor(obj, key) ?? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), key);
if (d && typeof d.value === 'function') {
jest.spyOn(obj, key).mockImplementation(newValue);
} else {
jest.replaceProperty(obj, key, newValue);
} Type guard
const isMethodValue = (o: object, k: PropertyKey) => {
let d = Object.getOwnPropertyDescriptor(o, k);
let p = Object.getPrototypeOf(o);
while (!d && p) { d = Object.getOwnPropertyDescriptor(p, k); p = Object.getPrototypeOf(p); }
return !!(d && typeof d.value === 'function');
};
if (isMethodValue(obj, key)) {
jest.spyOn(obj, key);
} else {
jest.replaceProperty(obj, key, value);
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: Copy-pasting a replaceProperty call where a method needed spying; refactor that turned a data property into a method without updating tests.
Related errors
- Cannot spy on the `${methodKey}` property because it is not
- Cannot use spyOn on a primitive value; ${typeOfObject} given
- Cannot spy on the ${propertyKey} property because it is not
- Cannot use replaceProperty on a primitive value; ${typeOfObj
- No property name supplied
AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03).
Data as JSON: /data/errors/bcf74920ac94c12a.json.
Report an issue: GitHub.