How to make Jest wait for all asynchronous code to finish execution before expecting an assertion
Here's a snippet that waits until pending Promises are resolved:
const flushPromises = () => new Promise(setImmediate);
Note that setImmediate is a non-standard feature (and is not expected to become standard). But if it's sufficient for your test environment, should be a good solution. Its description:
This method is used to break up long running operations and run a callback function immediately after the browser has completed other operations such as events and display updates.
Here's roughly how to use it using async/await:
it('is an example using flushPromises', async () => {
const wrapper = mount(<App/>);
await flushPromises();
wrapper.update(); // In my experience, Enzyme didn't always facilitate component updates based on state changes resulting from Promises -- hence this forced re-render
// make assertions
});
I used this a lot in this project if you want some working real-world examples.
I'm unaware of anything native to React to accomplish what you're looking for.
However, I was able to accomplish this in similar code by calling beforeAll()'s @done after setup was complete. See changes to your code below:
let setupComplete;
jest.mock('eternalService', () => {
return jest.fn(() => {
return { doSomething: jest.fn((cb) => { cb('fakeReturnValue'); setupComplete(); }) };
});
.
.
.
beforeAll(done => {
parent = mount(<Parent />)
setupComplete = done;
});
});
I've never used them, but of potential interest is Jest's runAllTicks and runAllImmediates.
I would suggest you export aThingThatReturnsAPromise()
from its module or file and then import it into your test case.
Since aThingThatReturnsAPromise()
returns a promise, you can make use of the asynchronous testing features of Jest. Jest will wait for your promise to resolve and then you can make your assertions.
describe('When rendering Parent', () => {
var parent;
beforeAll(() => {
parent = mount(<Parent />)
});
it('should display Child with response of the service', () => {
expect.assertions(1);
return aThingThatReturnsAPromise().then( () => {
expect(parent.html()).toMatch('fakeReturnValue');
});
});
});
For more info, read how Jest handles test cases with Promises in the Jest Docs here