jest
jest copied to clipboard
[Feature]: add `expect(spy).toHaveResolvedWith` for spies on async functions
🚀 Feature Proposal
Add a matcher for spies that spy on async functions.
Motivation
When spying on async functions, the received value of expect(spy).toHaveReturnedWith is always a Promise. This causes the tests to fail.
One way to go around this is to manually retrieve the Promise from the mock's metadata and await it.
See: https://github.com/plbstl/minimal-reproduction-jest-expect-tohavereturnedwith/blob/8e070ed6fb3757f5cf36a0550e1d6a5a31bebfd3/tests/index.test.ts#L14
It would be nice if expect(spy).toHaveReturnedWith automatically handles this or a new matcher (for example, toHaveResolvedWith) is created specifically for this use case.
Example
expect(asyncFunctionSpy).toHaveResolvedWith('expected')
Pitch
As helpful as the toHaveReturnedWith matcher when dealing with async code.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
...
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
...
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
a new matcher (for example,
toHaveResolvedWith) is created specifically for this use case
And toHaveRejectedWith for parity
Honestly, I was surprised by the lack of these matchers. The workaround for not having a toHaveResolvedWith is currently:
// If all is well, this should be a Promise
const results = mockSomeOtherWork.mock.results[0].value;
// If that Promise resolves to the right stuff, gucci!
const expected = [my, array, of, expected, values];
await expect(results).resolves.toStrictEqual(expected); // passes correctly
// This should fail, because the promise resolved to `expected`
const notExpected = [something, else];
await expect(results).resolves.toStrictEqual(notExpected); // fails correctly
(https://stackoverflow.com/a/62779249/2928233)
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
🙃
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
🫠
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
…
+1 for toHaveResolvedWith and toHaveRejectedWith.
I also second this feature suggestion.
There is at least one StackOverflow Q/A related to this: https://stackoverflow.com/a/62779249/636849
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
I was taking a look at the code of toHaveReturnedWith and it does not seem so hard to implement.
With a little luck I should be able to implement at least a basic version of it until the next weekend.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
I started coding some matchers, curently toHaveResolved, toHaveRejected and toHaveResolvedTimes are finished.
I am thinking about following jest and implementing toHaveX, toHaveXTimes, toHaveXWith, toHaveLastXWith and toHaveNthXWith for Resolved and Rejected.
With some luck it should be finished by next week.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
lol, almost finished, just making some tests and I will publish.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
…
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.