Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing a redux action

I am trying to implement jest with our redux actions. Given the below action foo and it's following test, the following test is failing because store.getActions() is only returning me [{"type": "ACTION_ONE"}] as supposed to [{"type": "ACTION_ONE"}, {"type": "ACTION_TWO"}]. How do I get both dispatched actions when testing? Thanks!

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

export const foo = () => {
  return (dispatch) => {
    dispatch(actionOne());
    return HttpService.get(`api/sampleUrl`)
      .then(json => dispatch(actionTwo(json.data)))
      .catch(error => handleError(error));
  };
};

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

beforeEach(() => {
  store = mockStore({});
});

describe('sample test', () => {
  test('validates foo complex action', () => {
    const expectedActions = [
      {type: actionTypes.ACTION_ONE},
      {type: actionTypes.ACTION_TWO},
    ];

    return store.dispatch(actions.foo())
      .then(() => {
        expect(store.getActions())
          .toEqual(expectedActions);
      });
  });
});
like image 854
Jimmy Avatar asked Feb 13 '19 19:02

Jimmy


People also ask

How do you test for reducers in jest?

To test Reducers, you can call them with a specific input state and action and assert that the resulting state matches expectations. The following example tests reducers and also use actions implementation in it. We wrote this example in typescript.

How do you mock react in Redux?

mock("react-redux", () => ({ useSelector: jest. fn(), useDispatch: jest. fn(), })); const mockSelectors = (selector, store) => { if (selector === ourSuperComplexCustomSelector) { return true; // or what we want to } return selector(store); } describe('Test TargetComponent', () => { beforeEach(() => { useDispatchMock.


1 Answers

You haven't mocked the API call and since it won't success without a mock, the action dispatched when the promise resolves is not fired. You can use fetchMock to mock the API call. Once you do that correctly, your test will work

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock';
import fetch from 'node-fetch';

export const foo = () => {
  return (dispatch) => {
    dispatch(actionOne());
    return fetch(`api/sampleUrl`)
      .then(r => r.json())
      .then(json => dispatch(actionTwo(json)))
      .catch(error => handleError(error));
  };
};

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

beforeEach(() => {
  store = mockStore({});
  fetchMock.restore()
});

describe('sample test', () => {
  test('validates foo complex action', () => {

    fetchMock.getOnce('api/sampleUrl', {
      body: { sample: ['do something'] }
    })

    const expectedActions = [
      {type: actionTypes.ACTION_ONE},
      {type: actionTypes.ACTION_TWO},
    ];

    return store.dispatch(actions.foo())
      .then(() => {
        expect(store.getActions())
          .toEqual(expectedActions);
      });
  });
});
like image 129
Shubham Khatri Avatar answered Oct 24 '22 05:10

Shubham Khatri