Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Jest does not play well with decorators: this refs do not work inside expect(fcn) calls #15061

Closed
jsrozner opened this issue May 8, 2024 · 1 comment

Comments

@jsrozner
Copy link

jsrozner commented May 8, 2024

Version

29.7.0

Steps to reproduce

Run jest on the following minimal test with a basic decorator.

function decorator(
  target: Object,
  propertyKey: string,
  descriptor: PropertyDescriptor,
) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    // BUG: `this` is undefined when run with, e.g., expect(decoratedFcn).toThrow()
    console.log(
      `Log instance var; should not be undefined: ${JSON.stringify(this)}`,
    );
    return originalMethod.apply(this, args);
  };
}
class SimpleClass {
  constructor(public name: string) {}
  @decorator
  logme() {
    // BUG: when called from `expect(simpleClassInstance.logme).not.toThrow()`, `this` is undef
    console.log(this.name);
  }
}

test("jest decorator", () => {
  const sc = new SimpleClass("somename");
  sc.logme(); // this works

  // this fails: `this` is not available in the decorated logme()
  expect(sc.logme).not.toThrow();
});

Expected behavior

expect(obj.decoratedFcn).not.toThrow()
should behave the same as if we just called obj.decoratedFcn()

Actual behavior

expect(decoratedFunction).toThrow() results in this (which should be the instance on which the decoratedFunction is being called) being undefined

The issue is observed in both

  • in descriptor.value redefinition (this is undefined)
  • in the original decorated function: this in logme() is undefined
  • (these correspond to the same underlying problem)

Additional context

No response

Environment

System:
    OS: macOS 14.4.1
    CPU: (14) arm64 Apple M3 Max
  Binaries:
    Node: 21.6.1 - ~/.nvm/versions/node/v21.6.1/bin/node
    Yarn: 4.1.0 - ~/.nvm/versions/node/v21.6.1/bin/yarn
    npm: 10.2.4 - ~/.nvm/versions/node/v21.6.1/bin/npm
  npmPackages:
    jest: ^29.7.0 => 29.7.0
@jsrozner
Copy link
Author

jsrozner commented May 8, 2024

Whelp, this was a dumb issue of passing around a function pointer that had dropped this context.

The fix is
expect(() => sc.logme()).not.toThrow();

@jsrozner jsrozner closed this as completed May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant