0

I have an action:

export const GetChatList = userStatus => {
  return dispatch => {
    dispatch({
      type: MessagesActionTypes.GET_MESSAGES_LIST.REQUEST,
      payload: {}
    });

    axios
      .get(config.apiUrl + config.methods.getMessagesList, { params: { accountType: userStatus } })
      .then(res => {
        dispatch({
          type: MessagesActionTypes.GET_MESSAGES_LIST.SUCCESS,
          payload: res.data
        });
      })
      .catch(err => {
        dispatch({
          type: MessagesActionTypes.GET_MESSAGES_LIST.ERROR,
          payload: 'error text'
        });
      });
  };
};

And I tried to write a test for this action:

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

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

  it('GetChatList', () => {
    fetchMock.get(config.apiUrl + config.methods.getMessagesList, { params: { accountType: 1 } });

    const expectedActions = [
      { type: MessagesActionTypes.GET_MESSAGES_LIST.REQUEST },
      {
        type: MessagesActionTypes.GET_MESSAGES_LIST.SUCCESS,
        payload: ...somePayload
      },
      {
        type: MessagesActionTypes.GET_MESSAGES_LIST.ERROR,
        payload: 'error text'
      }
    ];

    const store = mockStore({...initialState});
    return store.dispatch(GetChatList(1)).then(() => expect(store.getActions()).toEqual(expectedActions));
  });
});

And then I get an error: TypeError: Cannot read property 'then' of undefined Why is this happening and how to properly test this action? What are my mistakes?

1 Answer 1

1
  • fetch-mock mocks HTTP requests made using fetch. But you are using axios.

  • You should return the promise created by axios.get() in the thunk. So that you can call store.dispatch(GetChatList(1)).then() method.

  • You can use jest.spyOn(axios, 'get') to mock axios.get() method and its resolved/rejected value.

E.g.

thunk.ts:

import axios from 'axios';

export const MessagesActionTypes = {
  GET_MESSAGES_LIST: {
    REQUEST: 'REQUEST',
    SUCCESS: 'SUCCESS',
    ERROR: 'ERROR',
  },
};
const config = {
  apiUrl: 'http://localhost:8080/v1/api',
  methods: {
    getMessagesList: '/messages',
  },
};
export const GetChatList = (userStatus) => {
  return (dispatch) => {
    dispatch({ type: MessagesActionTypes.GET_MESSAGES_LIST.REQUEST, payload: {} });
    return axios
      .get(config.apiUrl + config.methods.getMessagesList, { params: { accountType: userStatus } })
      .then((res) => dispatch({ type: MessagesActionTypes.GET_MESSAGES_LIST.SUCCESS, payload: res.data }))
      .catch((err) => dispatch({ type: MessagesActionTypes.GET_MESSAGES_LIST.ERROR, payload: 'error text' }));
  };
};

thunk.test.ts:

import { GetChatList, MessagesActionTypes } from './thunk';
import configureStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import { AnyAction } from 'redux';
import axios from 'axios';

interface AppState {}
type DispatchExts = ThunkDispatch<AppState, void, AnyAction>;
const mws = [thunk];
const mockStore = configureStore<AppState, DispatchExts>(mws);

describe('71296970', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should pass', () => {
    jest.spyOn(axios, 'get').mockResolvedValue({ data: 'fake data' });
    const store = mockStore({});
    const expectedActions = [
      { type: MessagesActionTypes.GET_MESSAGES_LIST.REQUEST, payload: {} },
      { type: MessagesActionTypes.GET_MESSAGES_LIST.SUCCESS, payload: 'fake data' },
    ];

    return store.dispatch(GetChatList(1)).then(() => {
      const actions = store.getActions();
      expect(actions).toEqual(expectedActions);
    });
  });
});

Test result:

 PASS  stackoverflow/71296970/thunk.test.ts
  71296970
    ✓ should pass (5 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 thunk.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.383 s
Sign up to request clarification or add additional context in comments.

4 Comments

thanks a lot! Can you explain me how to send params in jest.spyOn('axios', get) ?
@БатрадзСанакоев Please explain what you want to achieve. What do you mean by "send params"?
Let's rephrase, I changed the code according to your advice, but then I got an error: when a successful action is executed, my payload is undefined. I can't understand why. What are my mistakes? jest.spyOn(axios, 'get').mockResolvedValue({ id: 1, userId: 'someId', userName: 'username', text: 'text' }); const expectedActions = [....{ type: MessagesActionTypes.GET_MESSAGES_LIST.SUCCESS, payload: id: 1, userId: 'someId', userName: 'username', text: 'text' }...]
I solved my problem, I forgot to write 'data' in 'mockResolvedValue'

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.