Search code examples
javascriptajaxxmlhttprequestnock

Nock is intercepting my request, but my AJAX request is erroring out


I'm testing an AJAX request made using XMLHttpRequest:

export default function requestToTest() {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.com/service');

  xhr.onload = () => {
    console.log('onload');
    // etc.
  };

  xhr.onerror = () => {
    console.log('onerror');
    // etc.
  };

  xhr.send();
}

So I set up a test using Nock (and Mocha):

describe('requestToTest()', () => {
  it('should handle a successful request', () => {
    nock('https://example.com')
      .log(console.log)
      .get('/service')
      .reply(200, { some: 'json' });

    requestToTest();

    expect( /* things I want to check */ ).to.be.true;
  });
});

When I run this test, xhr.onerror() fires, not xhr.onload(). However, from observing Nock's output from the call to log(), I know for certain that Nock is intercepting my AJAX request and that the intercepted request matches Nock's expected URL.

Why is xhr.onerror being called instead of xhr.onload in my test?


Solution

  • As a workaround, I used the isomorphic-fetch library. This library is an alternative to XMLHttpRequest for making AJAX requests and is expressly designed to work more or less identically in browser environments and in Node.js/test environments.

    In general, using a library designed to smooth out the differences between AJAX requests in the browser and making a request from the testing environment seems like the solution to this problem.