reduxjs / redux-mock-store

A mock store for testing Redux async action creators and middleware.
MIT License
2.5k stars 147 forks source link

Actions dispatched after using Promise.all don't save to store #164

Closed aerozen3 closed 4 years ago

aerozen3 commented 5 years ago

When I use Promise.all, I noticed that any dispatched actions don't get saved to the store afterwards. The code runs, but the store does not accurately reflect the dispatched actions. Here's an example (if I uncomment and use the promise directly instead, it works and the test passes):

export function tester(): Thunk<void> {
  const actionTest = (message: string) => {
    return {
      type: 'MESSAGE_TYPE',
      payload: { message },
    };
  };
  return (dispatch, getState) => {
    dispatch(actionTest('1'));
    const p = new Promise((resolve) => resolve('123'));
    //The following Promise.all causes the test to fail, but if I use the promise directly `p.then(() => {` it works.
    Promise.all([p]).then(() => {
      dispatch(actionTest('2'));
    });
  };
}
  it('test', async () => {
    await mockStore.dispatch(actions.tester());
    expect(mockStore.getActions()).toHaveLength(2);
  });

When using Promise.all, store.getActions() only has 1 action. When using the promise by itself p.then ..., the store has both actions. In both cases both dispatches are called.

jednano commented 5 years ago

You need to return your Promise.all to make this an actual async action or you won't be waiting for the Promise resolution.

return Promise.all([p]).then(...)

I tested this locally and it fixes your issue.

Also, if you're using async/await, you can return async dispatch =>.

Also, new Promise(resolve => resolve('123')) is the same as just Promise.resolve('123').

Your final tester function should look like this:

dmitry-zaets commented 4 years ago

See https://github.com/dmitry-zaets/redux-mock-store/issues/71 for more explanations