Closed yakirn closed 3 years ago
Great question! It looks like there's an open PR in jest-extended
that fixes this issue.
The root of the problem is that Mock
and MockedFunction
are both based on MockInstance
, but are different types.
This could be solved two ways:
toHaveBeenCalledAfter
could take a MockInstance
, not a Mock
. This is what the PR for jest-extended
does.MockedFunction
could be based on Mock
. This is probably the best solution.Both probably need to happen.
I've made a draft PR in @types/jest
, but I don't have time to finish it before my next meeting. I'll try to get back to it soon. Feel free to run with it if you want!
@yakirn Maybe you could cast to MockInstance
in the meantime? At least it's better than any
.
expect(chrome.tabs.update).toHaveBeenCalledAfter(chrome.cookies.set as jest.MockInstance);
@jacksteamdev casting to jest.Mock did the trick!
expect(chrome.tabs.update).toHaveBeenCalledAfter(chrome.cookies.set as jest.Mock);
jest.MockInstance
is a generic that requires two arguments, but also jest.MockInstance<any, any>
failed with:
interface jest.MockInstance<T, Y extends any[]> Argument of type 'MockInstance<any, any>' is not assignable to parameter of type 'Mock<any, any>'. Type 'MockInstance<any, any>' is missing the following properties from type 'Mock<any, any>': apply, call, bind, prototype, and 5 more.ts(2345)
Anything left to do with the PR do DefinitelyTyped? If you can fill me in I can try and continue over the weekend.
@yakirn I finished the DefinitelyTyped PR. I wanted to add some tests. We'll see how it goes 🤞
We should upvote the PR in jest-extended
, which needs to get merged.
Thank you so much @jacksteamdev ! I upvoted and I’ll ask my coworkers to do the same :)
@yakirn It looks like these PRs probably won't go anywhere fast. :disappointed:
But, we can use module augmentation to fix it locally. Create a declaration file, (ie, jest-mocked-function.d.ts
), and put this in it:
/// <reference types="jest" />
declare namespace jest {
interface Matchers {
/**
* Use `.toHaveBeenCalledBefore` when checking if a `MockInstance` was called before another `MockInstance`.
*
* Note: Required Jest version >=23
*
* @param {MockInstance} mock
*/
toHaveBeenCalledBefore(mock: jest.MockInstance): R
/**
* Use `.toHaveBeenCalledAfter` when checking if a `MockInstance` was called after another `MockInstance`.
*
* Note: Required Jest version >=23
*
* @param {MockInstance} mock
*/
toHaveBeenCalledAfter(mock: jest.MockInstance): R
}
interface Expect {
/**
* Use `.toHaveBeenCalledBefore` when checking if a `MockInstance` was called before another `MockInstance`.
*
* Note: Required Jest version >=23
*
* @param {MockInstance} mock
*/
toHaveBeenCalledBefore(mock: jest.MockInstance): R
/**
* Use `.toHaveBeenCalledAfter` when checking if a `MockInstance` was called after another `MockInstance`.
*
* Note: Required Jest version >=23
*
* @param {MockInstance} mock
*/
toHaveBeenCalledAfter(mock: jest.MockInstance): R
}
}
I've tried it out like this, and it works for me!
import { chrome } from "jest-chrome";
import "jest-extended";
test('toBeCalledAfter allows MockedFunction', () => {
expect(chrome.alarms.clear).toHaveBeenCalledAfter(chrome.alarms.create)
})
Hey, First of all, thank you for an awesome extension! Second, please see this unanswered question. It's more of a quality of life thing than an actual issue (I hate to use
any
in TS). Figured since the code works just fine there must be a less risky way to tell TS it's fine. The assertion is from jest-extendedTL;DR I'm trying to make TS to accept the following line but without casting to
any
:expect(chrome.tabs.update).toHaveBeenCalledAfter(chrome.cookies.set as any);
Thanks!