2

Hello I have some problems with testing react redux async actions every time i run the test I am receiving this array [{"type": "LOGIN"}] instead of this:

[{"type": "LOGIN"}, {"body": {"data": {"token": "1ca9c02f-d6d2-4eb8-92fd-cec12441f091", "userName": "8888888888888888"}}, "type": "LOGIN_SUCCESS"}]

Here are my code snippets:

The code from the actions:

export const LOGIN = 'LOGIN';
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LOGIN_ERROR = 'LOGIN_ERROR';

import { Api } from '../../../constants/api';

const api = new Api();

function loginSuccess(data) {
  return {
    type: LOGIN_SUCCESS,
    data,
  };
}

function loginError(error) {
  return {
    type: LOGIN_ERROR,
    error,
  };
}

export function login(fields) {
  return async dispatch => {
    dispatch({ type: LOGIN });
    api
      .register(fields.vin)
      .then(response => {
        const data = Object.assign(response.data, fields);
        return dispatch(loginSuccess(data));
      })
      .catch(error => dispatch(loginError(error)));
  };
}

And the code from the action.test file:

import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import fetchMock from 'fetch-mock';
import * as actions from './actions';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

describe('async actions', () => {
  afterEach(() => {
    fetchMock.reset();
    fetchMock.restore();
  });

  it('creates LOGIN_SUCCESS when fetching data has been done', () => {
    fetchMock.getOnce('/register', {
      body: {
        data: {
          userName: '8888888888888888',
          token: '1ca9c02f-d6d2-4eb8-92fd-cec12441f091',
        },
      },
      headers: { 'content-type': 'application/json' },
    });

    const expectedActions = [
      { type: actions.LOGIN },
      {
        type: actions.LOGIN_SUCCESS,
        body: {
          data: {
            userName: '8888888888888888',
            token: '1ca9c02f-d6d2-4eb8-92fd-cec12441f091',
          },
        },
      },
    ];

    const store = mockStore({ data: { id: null, token: null, userName: null } });

    return store.dispatch(actions.login({ id: '8888888888888888' })).then(response => {
      expect(store.getActions()).toEqual(expectedActions);
    });
  });
});

This is the first time testing async actions so I'm not sure what's going wrong.

1
  • You do not need to mention async in the action here return async dispatch => { dispatch({ type: LOGIN }); , you should just write return dispatch => { dispatch({ type: LOGIN }); Commented Jan 22, 2018 at 10:20

1 Answer 1

1

You need to return the API promise since you are resolving the promise in your test case

return store.dispatch(actions.login({ 
      id: '8888888888888888'
})).then(response => {          // resolving Promise here
  expect(store.getActions()).toEqual(expectedActions);
});

Your action must look like

export function login(fields) {
  return dispatch => {              // async is not needed here since no await is used
    dispatch({ type: LOGIN });
    return api                      // return here
      .register(fields.vin)
      .then(response => {
        const data = Object.assign(response.data, fields);
        return dispatch(loginSuccess(data));
      })
      .catch(error => dispatch(loginError(error)));
  };
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.