Search code examples
reactjsreduxaxiosredux-thunknock

Nock not working with axios get at actions async test


I am trying to test my async actions at redux but I am not getting it.

I am using nock and axios, so I am trying to receive a responde data from axios get to test my actions:

describe('Async Actions', () => {
    afterEach(() => {
        nock.cleanAll();
    });

    it('should load transmissors', (done) => {
        const localStorage = {
            token: 'a9sd8f9asdfiasdf'
        };
        nock('https://tenant.contactto.care')
                .get('/api/clients/1/transmissors/', {
                     reqheaders: { 'Authorization': "Token " + localStorage.token } 
                })
                .reply(200, { data: [
                    {
                        "id": 12,
                        "zone": "013",
                        "client": 1,
                        "description": "pingente",
                        "identifier": "",
                        "general_info": ""
                    },
                    {
                        "id": 15,
                        "zone": "034",
                        "client": 1,
                        "description": "colar",
                        "identifier": "",
                        "general_info": ""
                    }
                ]});

        axios.get(`/api/clients/1/transmissors/`, {
            headers: { 'Authorization': "Token " + localStorage.token },
        }).then(transmissors => { 
                console.log(transmissors);
        }).catch(error => {
            throw(error);
        })
        done();
    });
});

and here is my action:

 export function loadTransmissors(clientId){
        return function(dispatch){
            axios.get(`/api/clients/${clientId}/transmissors/`, {
                headers: { 'Authorization': "Token " + localStorage.token },
            }).then(transmissors => { 
                    dispatch(loadTransmissorsSuccess(transmissors.data, clientId));
            }).catch(error => {
                throw(error);
            })
        }
    }

But I receiving this error at console.log:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): SyntaxError

I found this answer from Dan Abramov: How to unit test async Redux actions to mock ajax response

https://github.com/reactjs/redux/issues/1716

Does anyone know how to make a test with redux-thunk.withExtraArgument?

Thanks in advance.


Solution

  • I solved my problem injecting axios via argument at redux thunk https://github.com/gaearon/redux-thunk#injecting-a-custom-argument

    So I changed my redux thunk at my store:

    applyMiddleware(thunk)
    

    for

    applyMiddleware(thunk.withExtraArgument({ axios }))
    

    So I updated my async return functions at actions From:

    return (dispatch) => {
       ...
    }
    

    To:

    return (dispatch, getState, { axios }) => {
       ...
    }
    

    at my actions.test I mocked an api with promises:

    const axios = {
            get: (url,params) => Promise.resolve({data: transmissors})
    }
    

    injected at redux thunk:

        const middleware = [thunk.withExtraArgument({axios})];
        const mockStore = configureMockStore(middleware);
    
        function asyncActions () {
          return dispatch => {
            return Promise.resolve()
              .then(() => dispatch(transmissorsActions.loadTransmissors(1)))
          }
        }
    

    and I used the function asyncActions to test my actions at my store:

    it('should load transmissors', (done) => {  
            const expectedAction = { type: types.LOAD_TRANSMISSORS_SUCCESS,  transmissors, clientId};
    
            const store = mockStore({transmissors: [], expectedAction});
            store.dispatch(asyncActions()).then(() => {
                const action = store.getActions();
                expect(action[0].type).equal(types.LOAD_TRANSMISSORS_SUCCESS);
                expect(action[0].transmissors).eql(transmissors);
                expect(action[0].clientId).equal(1);
            });
            done();
    
        });
    

    You can have more info about redux-mock-store with this sample: https://github.com/arnaudbenard/redux-mock-store/blob/master/test/index.js