Msw: Axios never receives response object

Created on 22 May 2020  路  22Comments  路  Source: mswjs/msw

Looking to integrate msw into our testing, using serverSetup in our jest tests, and feel like I must be missing something simple. I've setup my handlers, and can log my request coming into the resolve. However, that response never seems to make it to Axios, so the mock response never makes it to my interface. No response is received, no error is thrown, just...nothing

Environment

  • msw: 0.17.0
  • nodejs: 10.14.0
  • npm: 6.13.4
  • axios: 0.19.2

I'm running these tests via jest in a VS Code Terminal on a 2019 MacBook Pro (latest VS Code)

To Reproduce

I have setup a super simple test

import { rest } from 'msw';
import { setupServer } from 'msw/node';
import axios from 'axios';

describe('Axios test', () => {
  const handlers = [
    rest.get('/health/PeopleManagement/api/Person', (req, res, ctx) => {
      console.log('in request');
      return res(
        ctx.json({
          total: 0,
          data: [],
          count: 0,
        })
      );
    }),
  ];
  const server = setupServer(...handlers);

  beforeAll(() => server.listen());
  afterAll(() => server.close());

  it('should make a call for data', async () => {
    try {
      const types = await axios.get('/health/PeopleManagement/api/Person');
      console.log('types ', types);
    } catch (err) {
      console.error(err);
    }
  });
});

Expected behavior

You expect to see the console.log from the handler, that the call would resolve, and that types would now be the simple object and output to the console (or at least an error in the catch)

Current behavior

Instead, what you see is the console.log from the handler (we made it to the handler), followed by this error:

Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error

Axios

Under the hood, axios (in a node execution context like this) uses either http or https for it's transport, depending on the url protocol involved. It does this via this adapter.

Final Bit

Not sure what I'm doing wrong here. Do I require a custom request handler of some sort? Custom context? Been hammering away for a few hours now, and just getting nowhere...

bug tests node

Most helpful comment

Hey guys, I'm facing the same problem, any news about it?

All 22 comments

Hey, @cutterbl, thanks for raising this. I had an exact same issue when writing integration tests for axios, and the problem was in the XMLHttpRequest patch from node-request-interceptor. That's the library that's responsible for requests interception in NodeJS environment. The reason was in the wrong handling of the readyState event in XHR, which led axios (which uses fetch that's polyfilled with XMLHttpRequest in jsdom) to hang forever on the request, although being properly intercepted (as you can witness from your custom log message in the request handler).

The fix was introduced in [email protected] (release notes, integration test using axios). Could you please check what version of that package do you have installed (msw installs it as a dependency)?

$ npm ls node-request-interceptor

Let me know if it's 0.2.4. Perhaps, there was a dependency update issue and [email protected] doesn't ship with the proper dependency version with a fix. Thanks.

yes, seeing version 0.2.4 in msw and nowhere else

@kettanaito
I have created this tester project that you can use to reproduce the axios vs. fetch issue.
https://github.com/andreawyss/msw-tester
npm i
npm run test fetch works but axios does NOT work.
npm start fetch and axios both work in the browser.

Thanks for providing more info and for the reproduction repository, folks.

@andreawyss all tests pass in that repo for me given NodeJS 10.18.1. The issue may be related to the version of node that's used in the project. MSW and its stack uses v10.18.1+, so I'd strongly advice to use that version as well. Also, please update the msw package, it's listed as 0.15.0 in the repo.

Could you please try to provide those changes and let me know if that helps?

@kettanaito please retry with node v12.14.1

@kettanaito I have switched to 10.18.1, then to 12.14.1, and get the same error, so it doesn't appear to be a node version difference (at least in this case).

Stepping through axios source, it may be that you've applied request interceptors, but no response interceptors? Just a thought ...

@kettanaito
I have updated the tester https://github.com/andreawyss/msw-tester to use:

   "msw": "0.17.0",
   "node-request-interceptor": "0.2.4",
...
  "resolutions": {
    "node-request-interceptor": "0.2.4"
  },

And the axios test still is not passing on any node version.
I have installed nvm and retested using these node versions:

      v10.18.1
      v10.20.1
      v12.14.1
      v12.16.3
      v14.3.0

tested on macOS 10.15.4

Okay, I've spotted that while it works with locally linked modules (latest published), it doesn't provide proper response when using latest published dependencies. That's some sort of black magic I'm to figure out.

@cutterbl, the technical reason for that is most likely that XMLHttpRequest override class does not close the response properly. The issue is that it leaves that XHR request open, so jest timeouts before the response is closed (which is never).

This is how I've fixed it for a basic axios/axios.get test:

https://github.com/mswjs/node-request-interceptor/blob/2b9a53c377f58966cab4e2845e3a6509955f7b33/src/XMLHttpRequest/XMLHttpRequest/XMLHttpRequestOverride.ts#L218,L222

But, obviously, there's something else at play.

Axios test

While I'm looking into this, could you please clone this repo and try to run the axios.test.ts test suite?

$ git clone https://github.com/mswjs/node-request-interceptor.git
$ cd node-request-interceptor
$ yarn install
$ yarn test test/response/axios.test.ts

If we join our forces, perhaps, we'll discover what's wrong. Thanks.

node-request-interceptor test/response/axios.test.ts works on my machine.

I believe I've figured it out. Although you see [email protected] installed, the msw package (specifically, its node/index.js bundle) _includes_ that node-request-interceptor of the previous version, which does not have this axios issue fixed.

You can easily check that by opening node_modules/msw/node/index.js@2369. There's a list of events to trigger when an XMLHttpRequest is done, and you should see something like this:

_this.response = mockedResponse.body || '';
_this.trigger('loadstart');
_this.trigger('load');

However, when compared to the latest release of node-request-interceptor, there are a few things missing:

https://github.com/mswjs/node-request-interceptor/blob/master/src/XMLHttpRequest/XMLHttpRequest/XMLHttpRequestOverride.ts#L211-L222

trigger('loadend') and this.readyState = this.DONE are crucial to properly close a request that has been mocked.

That makes me conclude that msw unexpectedly bundles the node-request-intereceptor, instead of treating it as an external dependency.

@andreawyss, I can see the tests in your example repository pass, once updated to [email protected]:

 PASS  src/procs/items-axios.test.ts
 PASS  src/procs/items-fetch.test.ts

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.442s
Ran all test suites.

@cutterbl, could you please also update to [email protected] and let me know whether your tests pass? Thanks.

@kettanaito
I have updated the tester to use [email protected] https://github.com/andreawyss/msw-tester
Everything works now. Thank you!

I have also added instructions on how to run msw-tester with https, since one needs a valid SSL certificate to use msw with https.

Running msw with an invalid SSL certificate may can cause cryptic errors like the one in issue #157

So glad to hear that! Interception of requests in node is still new, so there may be hiccups here and there. Hope for your understanding and cooperation in that to develop a great software in the end.

I hope that invalid certificate error isn't cryptic anymore, as msw should produce a meaningful error message when it cannot register.

Sorry guys, was on holiday. Yes, [email protected] does now appear to working with axios.

Hi all, I am experiencing this same issue with [email protected], but it works when I revert to [email protected]. It seems that there may be a regression of this bug.

Hey, @AustinNChristensen. Sorry to hear that. The original cause for the aforementioned issue has been fixed, there must be something else in play in case of your scenario. Please, could you provide more details (how the request is performed, what is the response, what is the error message)? Ideally, a reproduction repo where I can see this exception happening. Then I will be able to help. Thanks.

@AustinNChristensen you may want to check out #214. It's not clear if you are having issues in jest or in the browser, but if it's the latter, that issue may help

Hey guys, I'm facing the same problem, any news about it?

@venturalp, hey. Could you please open a new issue regarding your problem? Make sure to fill in the issue template, so we can help you more efficiently. Thanks.

Hello guys, I'm facing the same problem also.

msw ==> 0.19.5
nodejs ==> 13.12.0
yarn ==> 1.22.4
axios ==> 0.19.2

Sorry for the inconvenience, but I鈥檓 locking this issue.

The original cause of this issue has been fixed. If you are experiencing a similar problem, please open a separate issue in this repo. Since yours is most likely to have a different technical reason, it鈥檚 going to be much more convenient for us to investigate it and leave the outcome for posterity this way.

Thank you for understanding and looking forward to hear your feedback soon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dashed picture dashed  路  4Comments

lukesmurray picture lukesmurray  路  3Comments

otaciliolacerda picture otaciliolacerda  路  3Comments

baker-travis picture baker-travis  路  3Comments

veronesecoms picture veronesecoms  路  3Comments