Skip to content
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

async actions don't always return Promise #97

Closed
DCKT opened this issue May 5, 2017 · 6 comments
Closed

async actions don't always return Promise #97

DCKT opened this issue May 5, 2017 · 6 comments

Comments

@DCKT
Copy link

DCKT commented May 5, 2017

Hello,

I'm using this module for testing my React Native app and I have a little problem with one async actions which not work. The other works properly but not the last one :

Here is the test code :

/* eslint-env jest */

import createStore from 'redux-mock-store'
import thunk from 'redux-thunk'

const mockStore = createStore([thunk])

test('action should logout the user', () => {
  const mockedStore = mockStore({})

  mockedStore
    .dispatch(logout()) // return undefined
    .then(() => {
      expect(mockedStore.getActions()).toEqual([
        { type: types.RESET_ITEMS, items: ['credentials'] },
        { type: types.REMOVE }
      ])
    })
})

And the async action :

export const logout = () => (dispatch) => {
  dispatch(resetItems(['credentials']))
  dispatch({ type: types.REMOVE })
}

Do you have an idea about this ? If I put a setTimeout around the getActions function, the test pass properly.

Thanks for your help !

@arnaudbenard
Copy link
Contributor

You need to return a promise in your action

@DCKT
Copy link
Author

DCKT commented May 12, 2017

@arnaudbenard Hmm, I think I'v tried, I will try ASAP. Thanks for you answer :)

@davidpelayo
Copy link

@DCKT you can actually define your logout action as follows:

export const logout = () => (dispatch) => {
  dispatch(resetItems(['credentials']))
  return dispatch({ type: types.REMOVE });
}

or even:

export const logout = () => (dispatch) => 
  dispatch(resetItems(['credentials'])).then(() => dispatch({ type: types.REMOVE }));

@yodaddyp
Copy link

@DCKT Any luck with this? Having the same issue.

@DCKT
Copy link
Author

DCKT commented May 30, 2017

Hello @arnaudbenard

Sorry for the late reply, I've tried all the suggested answer but I got the same, it looks like dispatch is not a Promise (but it is).

@newyork-anthonyng
Copy link
Contributor

newyork-anthonyng commented May 30, 2017

@DCKT
As far as I know, dispatch itself doesn't return a Promise by default when using redux-thunk. It will only return what you explicitly return in the function created by your action creator. See this answer for more info

In your original implementation:

// action creator returns undefined
export const logout = () => (dispatch) => {
  dispatch(resetItems(['credentials']))
  dispatch({ type: types.REMOVE })
}

Your test is trying to run undefined.then() which is causing your error.

Similarly for the implementation that returns dispatch:

// incorrect: returns { type: types.REMOVE }
export const logout = () => (dispatch) => {
  dispatch(resetItems(['credentials']))
  return dispatch({ type: types.REMOVE });
}

Your test would be trying to run { type: types.REMOVE }.then() which would cause an error.

You need to explicitly return a promise.

// returns Promise.resolve(), which is thenable
export const logout = () => (dispatch) => {
  dispatch(resetItems(['credentials']));
  return Promise.resolve(removeItem());
};

In this instance, your test would be trying to read Promise.resolve().then() which would work.


On a side note, you could have also rewritten your test to not expect a promise:

// test file
test('action should logout the user', () => {
  const mockedStore = mockStore({})

  mockedStore.dispatch(logout());
  expect(mockedStore.getActions()).toEqual([
    { type: types.RESET_ITEMS, items: ['credentials'] },
    { type: types.REMOVE }
  ]);
})

I think this would be the correct fix to your problem. You shouldn't have to fit your source code into your tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants