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
Feature Request: fakePromise - collapsing/synchronizing promise chains #1800
Comments
Note: the implementation I had in mind is more like a |
what was the problem? or just sharing? |
@fatso83 it's a feature request for a |
OK, so I think my issue is rooted in the fact that jest's fake timers change timer behaviours. More specifically, using fake timers no longer enables you to schedule callbacks to be called after all promise chains are executed. I'll create an issue for the jest folks instead. Not sure |
EDIT: OK, so I think my issue is rooted in the fact that jest's fake timers change timer behaviours. More specifically, using fake timers no longer enables you to schedule callbacks to be called after all promise chains are executed.
I'll create an issue for the jest folks instead. Not sure fakePromise is of use to anyone otherwise 😅
Motivation
I have an object that has a timer that triggers a network request, and the returned response is passed through a promise chain (multiple
.then()
calls). The final callback in the promise chain is supposed to change my object's state.I want to test that a certain change is later on reflected in the object's state. The way I set out implementing this at first is by using a
fakeServer
to return the expected response, then I trigger the change, waiting for network request to be made (setImmediate
), waiting for the promise chain to complete (setImmediate
again), and then testing the state. Theoretically it should all work out. Wonderful!Except, I forgot to mention that I'm using Timer Mocks in jest, which flatten and synchronize the timers. Usually, you could call
setTimeout(callback)
and your callback is guaranteed to be called after all promises, but this is no longer the case here. Back to the drawing board...Solution
Ok, so the solution I arrived at is to modify the request function (
requests.postRequest()
in the above example) with a function that returns a synchronous promise. That implies that if you sandwich the promise between two synchronous tasks then the promise will be complete before the 2nd synchronous task:The implementation of a synchronous promise is pretty simple:
For the above example I can mock
requests.postRequest
like so:Alternatives
The most obvious alternative is placing your test at the end of a promise chain that's longer than the one you're trying to test (as mentioned here). This works! Moreover, my solution changes the behaviour of promises. For example:
So, if you somehow had code with interdependent promises then this might cause unexpected behaviour. Still, I find a chain of promises to be less clear than using fake promises for something like a network response.
The text was updated successfully, but these errors were encountered: