My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more

How to mock an async action creator in redux with jest?

slim's photo
slim
·Apr 23, 2019

I'm trying to write a unit test for a redux async action creator using jest. asyncActions.js:

const startSignInRequest = () => ({
  type: START_SIGNIN_REQUEST
});

// action creator to dispatch the success of sign In
export const signInSucceded = user => ({
  type: SIGNIN_USER_SUCCEEDED,
  user
});

// action creator to dispatch the failure of the signIn request
export const signInFailed = error => ({
  type: SIGNIN_USER_FAILED,
  error
});

const signInUser = user => dispatch => {
dispatch(startSignInRequest);
  return signInApi(user).then(
    response => {
      const { username, token } = response.data;
      dispatch(signInSucceded(username));
      localStorage.setItem("token", token);
      history.push("/homepage");
    },
    error => {
      let errorMessage = "Internal Server Error";
      if (error.response) {
        errorMessage = error.response.data;
      }
      dispatch(signInFailed(errorMessage));
      dispatch(errorAlert(errorMessage));
    }
  );
};

signInApi.js:

import axios from "axios";
import { url } from "../../env/config";

const signInApi = async user => {
  const fetchedUser = await axios.post(`${url}/signIn`, {
    email: user.email,
    password: user.password
  });
  return fetchedUser;
};

In the Writing tests of redux's official documentation, they use fetch-mock library. However, I think that this library call the real Api. I tried to mock the axios api using jest mocks.

/__mocks/signInApi.js:

const users = [
{
    login: 'user 1',
    password: 'password'
}
];

  export default function signInApi(user) {
    return new Promise((resolve, reject) => {
      const userFound = users.find(u => u.login === user.login);
      process.nextTick(() =>
        userFound
          ? resolve(userFound)
          // eslint-disable-next-line prefer-promise-reject-errors
          : reject({
              error: 'Invalid user credentials',
            }),
      );
    });
  }

__tests/asyncActions.js:

jest.mock('../axiosApis/signInApi');
import * as actions from '../actions/asyncActions';

describe('Async action creators', () => {
it('Should create SIGN_IN_USER_SUCCEEDED when signIn user has been done', () => {
    const user = {
                    login: 'user 1',
                    password: 'password'
                }
    expect(actions.signInUser(user)).resolves.toEqual({
        user
    })
})
});

The test failed and I got:

expect(received).resolves.toEqual()

    Matcher error: received value must be a promise

    Received has type:  function
    Received has value: [Function anonymous]

How can I mock this async action creator only with jest?