denoland/deno · error · TypeError

Cannot mock property '${String(methodName)}' because it does

Error message

Cannot mock property '${String(methodName)}' because it does not exist

What it means

mock.method() resolves the method via findPropertyDescriptor(), which walks the object's prototype chain, and throws this plain TypeError when no property with that name exists anywhere. You can only replace a method that is actually present, matching Node's behavior.

Source

Thrown at ext/node/polyfills/testing.ts:2498

    const desc = ObjectGetOwnPropertyDescriptor(current, name);
    if (desc) return desc;
    current = ObjectGetPrototypeOf(current);
  }
  return undefined;
}

function mockMethodImpl(object, methodName, implementation, options) {
  if (
    implementation !== null && typeof implementation === "object" &&
    typeof implementation !== "function"
  ) {
    options = implementation;
    implementation = undefined;
  }

  const descriptor = findPropertyDescriptor(object, methodName);
  if (!descriptor) {
    throw new TypeError(
      `Cannot mock property '${String(methodName)}' because it does not exist`,
    );
  }

  const isGetter = options?.getter ?? false;
  const isSetter = options?.setter ?? false;

  let original;
  if (isGetter) {
    original = descriptor.get;
  } else if (isSetter) {
    original = descriptor.set;
  } else {
    original = descriptor.value;
  }

  if (typeof original !== "function") {
    throw new TypeError(

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Verify the name exists before mocking: if (!('add' in math)) fail with a clear message
  2. Fix the typo / use the exact, case-sensitive method name
  3. Mock the object that actually owns the method (walk Object.getPrototypeOf if needed)
  4. For members that only appear via a Proxy trap, restructure so a real property exists - descriptor lookup cannot see traps

Example fix

// before
mock.method(math, 'addition', () => 3); // no such method

// after
mock.method(math, 'add', () => 3);
Defensive patterns

Strategy: validation

Validate before calling

function assertMockableMethod(o: object, name: PropertyKey): void {
  let t: object | null = o;
  while (t !== null) {
    if (name in t) return;
    t = Object.getPrototypeOf(t);
  }
  throw new Error(`refusing to mock missing method ${String(name)}`);
}

Type guard

function hasMethod(o: object, name: string): boolean {
  let t: object | null = o;
  while (t !== null) {
    if (name in t && typeof (t as Record<string, unknown>)[name] === 'function') return true;
    t = Object.getPrototypeOf(t);
  }
  return false;
}

Try / catch

try { mock.method(obj, name, impl); } catch (e) { if (e instanceof TypeError && /does not exist/.test(e.message)) throw new Error(`API surface changed: ${name}`); else throw e; }

Prevention

When it happens

Trigger: mock.method(math, 'addition') (typo for 'add'); mock.method(db, 'save') where save exists only as a Proxy get-trap so no real descriptor is found; mocking the instance when the method lives on an object the code never receives.

Common situations: Upstream renames/refactors of the mocked API; wrong receiver object passed to mock.method; case-sensitive name mistakes; dynamically created runtime methods.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/2e897407853a0c19. Report an issue: GitHub.