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

toHaveBeenCalledBefore and toHaveBeenCalledAfter don't accept result of jest.fn() #552

Closed
Lukas-Kullmann opened this issue Jan 24, 2023 · 1 comment

Comments

@Lukas-Kullmann
Copy link

Lukas-Kullmann commented Jan 24, 2023

Bug

  • package version: 3.2.3
  • node version: 18.13.0
  • npm (or yarn) version: 8.19.3

I want to use toHaveBeenCalledBefore (or ...After) with the result of a jest.fn(). However, I get a typescript error.

declare const myFn: (argument: string) => void;

expect(jest.fn()).toHaveBeenCalledAfter(jest.fn(myFn));
// ----- error is here -----------------^^^^^^^^^^^^^

This results in an error:

Argument of type 'Mock<void, [argument: string]>' is not assignable to parameter of type 'MockInstance<unknown, unknown[]>'.
  The types returned by 'getMockImplementation()' are incompatible between these types.
    Type '((argument: string) => void) | undefined' is not assignable to type '((...args: unknown[]) => unknown) | undefined'.
      Type '(argument: string) => void' is not assignable to type '(...args: unknown[]) => unknown'.
        Types of parameters 'argument' and 'args' are incompatible.
          Type 'unknown' is not assignable to type 'string'.(2345)

Here's a typescript playground link that basically reproduces the issue: playground link

I think the problem was introduced in #477 where the argument of toHaveBeenCalledAfter was changed from jest.MockInstance<any, any[]> to jest.MockInstance<unknown, unknown[]>.

If I change it back to the anys in my playground, I don't get the error.

Workaround

I fixed it temporarily in our project by creating my own .d.ts file with the following content.
However, it would be great if the library could fix it.

declare namespace jest {
  interface Matchers<R> {
    toHaveBeenCalledBefore(
      mock: jest.MockInstance<any, any[]>,
      failIfNoFirstInvocation?: boolean,
    ): R;
    toHaveBeenCalledAfter(
      mock: jest.MockInstance<any, any[]>,
      failIfNoFirstInvocation?: boolean,
    ): R;
  }
}
wh1t3cAt1k added a commit to wh1t3cAt1k/jest-extended that referenced this issue Mar 28, 2023
@wh1t3cAt1k wh1t3cAt1k mentioned this issue Mar 28, 2023
4 tasks
@keeganwitt
Copy link
Collaborator

keeganwitt commented Jun 5, 2023

What's interesting is this work fine

test('toHaveBeenCalledBefore and toHaveBeenCalledAfter empty', () => {
    const mock = jest.fn();
    expect(mock).not.toHaveBeenCalledAfter(mock);
    expect(mock).not.toHaveBeenCalledBefore(mock);
});

But this does not

test('toHaveBeenCalledBefore and toHaveBeenCalledAfter with mockFunction', () => {
    const myFn = (arg: string) => void {};
    expect(jest.fn()).not.toHaveBeenCalledAfter(jest.fn(myFn));
    expect(jest.fn()).not.toHaveBeenCalledBefore(jest.fn(myFn));
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants