jestjs/jest · error · TypeError
Cannot spy on the `${String(methodKey)}` property because it
Error message
Cannot spy on the `${String(methodKey)}` property because it is not a function; ${this._typeOf(original)} given instead.${typeof original === 'object' ? '' : ` If you are trying to mock a property, use `jest.replaceProperty(object, '${String(methodKey)}', value)` instead.`} What it means
Thrown by jest.spyOn (as a TypeError) when the property exists but is not a function. spyOn only wraps functions; for value properties the message actively suggests jest.replaceProperty. The replaceProperty hint is suppressed when the original is an object.
Source
Thrown at packages/jest-mock/src/index.ts:1305
}
if (accessType) {
return this._spyOnProperty(object, methodKey, accessType);
}
const original = object[methodKey];
if (!original) {
throw new Error(
`Property \`${String(
methodKey,
)}\` does not exist in the provided object`,
);
}
if (!this.isMockFunction(original)) {
if (typeof original !== 'function') {
throw new TypeError(
`Cannot spy on the \`${String(
methodKey,
)}\` property because it is not a function; ${this._typeOf(
original,
)} given instead.${
typeof original === 'object'
? ''
: ` If you are trying to mock a property, use \`jest.replaceProperty(object, '${String(
methodKey,
)}', value)\` instead.`
}`,
);
}
const isMethodOwner = Object.prototype.hasOwnProperty.call(
object,
methodKey,
);View on GitHub (pinned to 8e6d128e4a)
Solutions
- Use jest.replaceProperty(obj,'count',5) for value properties.
- If the property is backed by a getter, call jest.spyOn(obj,'prop','get').mockReturnValue(value).
- Confirm via typeof obj.method === 'function' before spying.
Example fix
// before jest.spyOn(config, 'timeout'); // timeout is a number // after jest.replaceProperty(config, 'timeout', 1000);
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof obj[methodKey] !== 'function') {
// value property -> use replaceProperty
jest.replaceProperty(obj, methodKey, value);
} else {
jest.spyOn(obj, methodKey);
} Type guard
const isMethod = <T extends object>(o: T, k: keyof T): boolean => typeof o[k] === 'function';
Prevention
- Check typeof obj.prop === 'function' before choosing spyOn vs replaceProperty.
- For accessor-backed values, use spyOn(obj, prop, 'get'|'set').
- Read the API surface of the module before writing spies.
When it happens
Trigger: jest.spyOn(obj,'count') when obj.count = 5; jest.spyOn(config,'timeout') when timeout is a number; jest.spyOn(obj,'items') when items is an array.
Common situations: Confusing a data property with a method; the API changed and a method became a value; trying to spy on a getter-backed value without the 'get' access type.
Related errors
- Cannot use spyOn on a primitive value; ${this._typeOf(object
- ${RECEIVED_COLOR('received')} value must be a mock or spy fu
- ${RECEIVED_COLOR('received')} value must be a mock function
- ${EXPECTED_COLOR('expected')} value must be a non-negative i
- No property name supplied
AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10).
Data as JSON: /api/errors/58263617c402be61.
Report an issue: GitHub.