Search code examples
reactjstestingreduxnock

Does nock only work if there is an Internet connection?


I've been having issues using nock to test my Redux action creators. When I go offline, I keep getting failed promises meaning the HTTP request using Axios was not successful. When I go online, it works, though.

So does nock only work if there is an Internet connection?

Action Creator (uses axios 0.15.3)

export const fetchSomething = (id) => {
  return dispatch => {
    dispatch({
      type: FETCH_SOMETHING_LOADING
    });

    return axios.get(`${SOMEWHERE}/something?id=${id}`)
      .then(response => {
        return dispatch({
          type: FETCH_SOMETHING_SUCCESS,
          payload: response.data
        });
      })
      .catch(error => {
        return dispatch({
          type: FETCH_SOMETHING_FAILURE
        });
      });
  };
};

Jest test for the action creator (nock v9.0.2)

test('should dispatch success action type if data is fetched successfully', () => {
  // Need this in order for axios to work with nock
  axios.defaults.adapter = require('axios/lib/adapters/http');

  nock(SOMEWHERE)
    .get('/something?id=123')
    .reply(200, someFakeObject);

  thunk = fetchSomething(123);

  return thunk(dispatch)
    .then(() => {
      expect(dispatch.mock.calls[1][0].type).toBe('FETCH_SOMETHING_SUCCESS');
    });
});

Solution

  • There seems to be some issues with using nock to test requests made by axios. There is an issue in nock's repository that discusses that.

    I found that @supnate's comment on that issue solved my problem. Furthermore, I had in my code a call to nock.cleanAll(); inside a beforeEach() construct that was the main culprit of the problem.

    The solution is to remove that. Don't use nock.cleanAll()! So now everything works well to test requests made by axios:

    import axios from 'axios';
    import httpAdapter from 'axios/lib/adapters/http';
    
    axios.defaults.host = SOMEWHERE; // e.g. http://www.somewhere.com
    axios.defaults.adapter = httpAdapter;
    
    describe('Your Test', () => {
      test('should do something', () => {
        nock(SOMEWHERE)
          .get('/some/thing/3')
          .reply(200, { some: 'thing', bla: 123 });  
    
        // then test your stuff here
      );
    });