Q:

Redux Mock Store giving 'Actions must be plain objects. Use custom middleware for async actions.'

I am trying to test some async code in my React app using redux-mock-store.
const configureMockStore = require('redux-mock-store').default;
const thunk = require("redux-thunk").default;

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

const dummy = () => {
  // Mock Ajax call
  return new Promise((resolve, reject) => {
      setTimeout(() => resolve({data: 'data'}), 200)
  })
};

describe("Redux Mock Store", () => {
  it("Test Dummy Ajax call", () => {
    const expectedActions = [
      { type: "SUCCESS", payload: "success" },
      { type: "FAILURE", error: { Error: "Error" } }
    ];
    const store = mockStore({});

    store.dispatch(dummy().then(() => {
              expect(store.getActions()).toEqual(expectedActions) 
           }).catch(error => { console.log(error) }))
  });
});

I am using Jest to run this test. I get the following error when running above test Actions must be plain objects. Use custom middleware for async actions. What's wrong here?

A:

The problem is that you are using redux-thunk middleware but you are not dispatching any action once your promise resolves (you can check how to define an action creator that uses redux-thunk in the documentation).
So, you need to define an action creator that uses your dummy ajax request and dispatches an action once it has finished:
const dummy = () => {
    // Mock Ajax call
    // Note that you are not capturing any error in here and you are not
    // calling the reject method, so your *catch* clausule will never be
    // executed.
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve({ data: 'success' }), 200);
    });
};

const actionCreator = () => (dispatch) => {
    return dummy()
        .then(payload => dispatch({ type: 'SUCCESS', payload }))
        .catch(error => dispatch({ type: 'FAILURE', error }));
};

Note how the action creator receives a parameter dispatch (that is provided by redux-thunk middleware) and we use that function to dispatch our actions (that are simple objects).
Once you call your action creator with the correct parameters, you should return your promise in the it so that it waits until the promise has resolved and executes the expects inside the then statement:
describe('Redux Mock Store', () => {
    it('Test Dummy Ajax call', () => {
        const expectedActions = [
            { type: 'SUCCESS', payload: { data: 'success' } },
        ];
        const store = mockStore({});

        return store.dispatch(actionCreator()).then(() => {
            expect(store.getActions()).toEqual(expectedActions);
        });
    });
});

Also, take into account that in your initial test you are expecting two actions to be dispatched, but you are only calling your action creator once. You should test the failure case in another it.
You can see the solution working here.

