-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
feat(@jest/mock): Add withImplementation #13281
Conversation
3d4d3c1
to
ecb89f1
Compare
For temporarily overriding mock implementations.
ecb89f1
to
c4cb677
Compare
Could you add type tests, please? For completeness and to make sure that generic types will work as expected for the user. The tests live in this file. To run them build the library and run |
I believe all the feedback has been addressed now. |
Co-authored-by: Tom Mrazauskas <[email protected]>
@mrazauskas |
Right, all looks good to me. So we have to wait for @SimenB, because only he is able to merge PRs. |
I like that idea! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice stuff!
packages/jest-mock/src/index.ts
Outdated
typeof returnedValue === 'object' && | ||
returnedValue !== null && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typeof returnedValue === 'object' && | |
returnedValue !== null && | |
returnedValue != null && | |
typeof returnedValue === 'object' && |
probably doesn't matter, but easier to bail out early
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Like I mentioned in one of my previous comments I copied this verbatim from jest circus.
So there's probably a nice tiny performance enhancement waiting to be made there as well:
https://github.com/facebook/jest/blob/a20fd859673800c50f8f089cfb4a87faec119525/packages/jest-circus/src/utils.ts#L271-L275
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we actually have https://github.com/facebook/jest/blob/c3a000e31343dd9e37da159e5903376c4312a0fd/packages/jest-util/src/isPromise.ts - should probably use that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha, the linked SO answer says not to use it 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened #13314
Co-authored-by: Simen Bekkhus <[email protected]>
Co-authored-by: Simen Bekkhus <[email protected]>
Remove redundant `async` Co-authored-by: Simen Bekkhus <[email protected]>
Change promise detection expression to bail out earlier for `null` and `undefined` Co-authored-by: Simen Bekkhus <[email protected]>
testFn(); | ||
expect(mock1).toHaveBeenCalled(); | ||
|
||
expect.assertions(3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering: should expect.assertions
be added to the examples in docs as well? I mean, if users must use expect
inside the callback, it would be good to show that in the example. Or?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the callback function will always be executed immediately by withImplementation
- no matter if it's async or not - I wouldn't think expect.assertions
is necessary outside of jest's own test suite. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right. Got it (;
I might be wrong but to me it seems that the failing job random and not related to the PR. If that job succeeds I believe this PR is ready to merge. - that is unless you have more comments. Btw. thank you for the thorough, kind, and useful reviews 👍, it's a great experience to contribute. |
Yeah, you can safely ignore that failure 👍 I'll land #13314, then merge main into this PR, then I'll land this one. Thanks for the patience and great contribution! 🎉 |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
A follow-up for #9270
It's often useful to override mock implementations for specific tests, and
mockImplementationOnce
is there to help out.It is however not a very elegant solution for situations where the mock will get called multiple times:
mockImplementationOnce
makes the number of calls unecessarily important.mockImplementationOnce
will bleed into the next test if the implementation does not end up getting called.This PR implements a new method
withImplementation
which sets a temporary default implementation which will be available within a callback, after which the default implementation will be set back to what it was before. If the callback returns a promise,withImplemenation
will return a promise that can be awaited in the test.I had to add a couple of
@ts-expect-error
comments to get the returned value ofwithImplementation
(promise or void) match the return value of the callback implementation. If you know a better way of achieving this, let me know.Also, I could potentially be useful to print a warning if the callback does not trigger a call to the mock - in which case
withImplementation
was redundant. What do you think about that idea?Test plan
I've added unit tests for the feature. Let me know if I need to add more tests.