简体   繁体   中英

How Can I test a an action reducer with an async call and dispatch inside using Jest?

I'm new in Jest and I'm trying to make test to my async action creators. The problem is that I only have seen examples of tests where there is a method for the action creator and other separate method for the dispatch. My actions creators have the dispatch as an async callback function, but I can't figure out how to make the test. My Action Reducer looks like this:

export const postConnection = (connectionUrl, username, password) => {
    return async (dispatch) => {
        const response = await requireAuthActions.post('/db/conexion', JSON.stringify({ connectionUrl, username, password }));
        dispatch({ type: POST_CONNECTION, payload: response.data });
        history.push('/conexiones');
    }
}

And I have trying to do the test script but when I run it it throws me an error. The script looks like this:

describe('Pruebas de Conexiones', () => {
    describe('Action Creators', () => {
        it("Crear conexión", async () => {
            const dispatch = jest.fn();
            const {data} = await postConnection('www.google.com', 'root', 'password')(dispatch);
            dispatch({});
        });
    });
});

And when I try to run the test script it throws me the next error:

Request failed with status code 401

      at createError (node_modules/axios/lib/core/createError.js:16:15)
      at settle (node_modules/axios/lib/core/settle.js:17:12)
      at IncomingMessage.handleStreamEnd (node_modules/axios/lib/adapters/http.js:237:11)

Is there a way of test actions creators like the mine?

EDIT Now I have a mocks file with a mock for axios that looks like this:

const mockAxios = jest.genMockFromModule('axios');

mockAxios.create = jest.fn(() => mockAxios)

export default mockAxios

But now my problems is that I don't know how to implement this in the test file. For now I have something like this:

import thunk from 'redux-thunk';
import mockAxios from 'axios';

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

describe('Test de conexiones', () =>{
    describe('Action Creators', () =>{
        it('Agregar conexión', async () =>{
            const store = mockStore({});
            const mockData = {data:123};
            mockAxios.get.mockImplementationOnce(()=>Promise.resolve({data: mockData}));

            const expectedActions = [
                {type: POST_CONNECTION, data: mockData}
            ]
            const dispatch = jest.fn();
            const response = await postConnection('www.google.com','root','password')(dispatch);
        });
    });
});

And it throws me the next error:

TypeError: Cannot read property 'data' of undefined

      12 |     return async (dispatch) => {
      13 |         const response = await requireAuthActions.post('/db/conexion', JSON.stringify({ connectionUrl, username, password }));
    > 14 |         dispatch({ type: POST_CONNECTION, payload: response.data });
         |                                                             ^
      15 |         history.push('/conexiones');
      16 |     }
      17 | }

I see 2 approaches possible: using real store or redux-mock-store

Steps are similar:

  1. Set up store.
  2. mock external API like http call or at least requireAuthActions module with some response(successful or failed)(check jest's docs on mocking )
  3. make a pause to await( await Promise.resolve(); , flush-promises or setTimeout(..., 0) ) all async things like Promise.resolve() you mocked in #2.
  4. if you use real store - then check against store(with selectors if you use this level of abstraction) if it contains data you would expect to see based on response you mocked in #2
  5. if it's redux-mock-store you cannot verify data in state(so reducers should be tested separately) so just validate list of actions generated - if they meet expectations based on response mocked in #2 or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM