0

I am trying to test my signupAction shown below.

import axios from 'axios';
import actionTypes from '../action_types';
import { apiRequest } from '../common_dispatch';

export const signupAction = (user) => async (dispatch) => {
  dispatch(apiRequest(true));
  await axios
    .post(`${process.env.REACT_APP_API_URL}/users`, { ...user }, {
      headers: { 'Content-Type': 'application/json' },
    })
    .then((response) => {
      dispatch(
        {
          type: actionTypes.REGISTER_SUCCESS,
          payload: response.data.user,
        },
      );
      dispatch(apiRequest(false));
    })
    .catch((error) => {
      let errors = 'ERROR';
      if (error.message === 'Network Error') {
        errors = error.message;
      } else {
        errors = error.response.data.errors;
        console.log(error);
      }
      dispatch(
        {
          type: actionTypes.REGISTER_FAIL,
          payload: errors,
        },
      );
      dispatch(apiRequest(false));
    });
};

I figured I could mock the API call above using the fetchMock library. The problem is fetchMock makes actual calls hence the test passes in the first intance but fails when I run it the second time because the user I am trying to sign up already exists. my test is as shown below.

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

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

describe('signUp actions', () => {
    afterEach(() => {
        fetchMock.resetMocks();
        console.log('yess bro am called')
    })

    it('dispatches create REGISTER_FAIL when signup has been done', async () => {
        fetchMock.postOnce('/users', { ...mocks.user }, {
            headers: { 'Content-Type': 'application/json' },
        });
        const expectedActions = [
            { type: 'API_REQUEST', payload: true },
            { type: 'REGISTER_FAIL', payload: { email: "Email karanilarrygmail.com is not a valid email" } },
            { type: 'API_REQUEST', payload: false },
        ]
        const store = mockStore(mocks.user);
        return store.dispatch(actions.signupAction(mocks.user)).then(() => {
            expect(store.getActions()).toEqual(expectedActions)
        })
    });


mocks.user is an object containing the user signup data.

What am I doing wrong

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Larry
  • 1
  • 2
  • interesting. Are you sure it reaches real backend? `fetch-mock` even unmatched requests should fail(until you set `fallbackToNetwork` to `true`). Probably, for some reason `axios` uses XmlHttpRequest instead of `fetch`. Try [`axios-mock-adapter`](https://github.com/ctimmerm/axios-mock-adapter) – skyboyer Mar 23 '20 at 12:11
  • @skyboyer yes am sure it hits the backed because the response I get comes from the backend i.e 'User already exists' – Larry Mar 23 '20 at 12:20

0 Answers0