{"record":{"id":"b3da6046082b5d7c","repo":"jestjs/jest","slug":"spyon-methodname-method-does-not-exist-us","errorCode":null,"errorMessage":"<spyOn> : ${methodName}() method does not exist\nUsage: spyOn(<object>, <methodName>)","messagePattern":"<spyOn> : (.+?)\\(\\) method does not exist\nUsage: spyOn\\(<object>, <methodName>\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-jasmine2/src/jasmine/spyRegistry.ts","lineNumber":100,"sourceCode":"    this.spyOn = (obj, methodName, accessType) => {\n      if (accessType) {\n        return this._spyOnProperty(obj, methodName, accessType);\n      }\n\n      if (obj === void 0) {\n        throw new Error(\n          getErrorMsg(\n            `could not find an object to spy upon for ${methodName}()`,\n          ),\n        );\n      }\n\n      if (methodName === void 0) {\n        throw new Error(getErrorMsg('No method name supplied'));\n      }\n\n      if (obj[methodName] === void 0) {\n        throw new Error(getErrorMsg(`${methodName}() method does not exist`));\n      }\n\n      if (obj[methodName] && isSpy(obj[methodName])) {\n        if (this.respy) {\n          return obj[methodName];\n        } else {\n          throw new Error(\n            getErrorMsg(`${methodName} has already been spied upon`),\n          );\n        }\n      }\n\n      let descriptor;\n      try {\n        descriptor = Object.getOwnPropertyDescriptor(obj, methodName);\n      } catch {\n        // IE 8 doesn't support `definePropery` on non-DOM nodes\n      }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-jasmine2/src/jasmine/spyRegistry.ts#L82-L118","documentation":"Thrown by SpyRegistry.spyOn when obj[methodName] is undefined (spyRegistry.ts:100). The method must exist on the object as an own or inherited property; spying on a non-existent method would silently create a fake that has no underlying behaviour, so Jest refuses.","triggerScenarios":"spyOn(obj, 'nonExistent'), spy on a method that was renamed in the library, spy on a prototype method using the instance (or vice versa), or spy on a method exported as a plain function rather than a member.","commonSituations":"Upgrading a dependency that renamed or removed a method; spying on a function-style export (`export const fn = () => {}`) which is not a member of any object; spying on a class method via the instance when the method is actually on a parent prototype not in the chain; typos in method names.","solutions":["Confirm the method exists: console.log(typeof obj.methodName) before spyOn.","For function-style exports, refactor to a member (obj.method = fn) or use jest.spyOn on a wrapper module.","Spy on the correct receiver: spyOn(MyClass.prototype, 'method') for instance methods shared across instances.","After a dependency upgrade, grep the changelog for the renamed method and update the spy."],"exampleFix":"// before\nspyOn(logger, 'logInfo'); // method renamed in v3\n// after\nspyOn(logger, 'info');","handlingStrategy":"validation","validationCode":"if (typeof obj[methodName] !== 'function') {\n  throw new Error(`spyOn: ${String(methodName)} is not a function on the target`);\n}\nspyOn(obj, methodName);","typeGuard":"const hasMethod = <T extends object>(o: T, k: string): k is keyof T & string =>\n  typeof (o as any)[k] === 'function';","tryCatchPattern":null,"preventionTips":["Assert the method exists before spying.","After dependency upgrades, grep changelogs for renamed methods.","Spy on prototypes for instance methods shared across instances."],"tags":["jest","spyon","mocking","missing-method","api-misuse"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}