axios-mock-adapter icon indicating copy to clipboard operation
axios-mock-adapter copied to clipboard

Request object is not defined on response

Open ghost opened this issue 7 years ago • 7 comments

const axiosMock = new MockAdapter(axios);
axiosMock.onGet(`${gl.TEST_HOST}/test`).reply(200, { some: 'data' });

axios.get(`${gl.TEST_HOST}/test`)
  .then(response => console.log(response.request));

will result in undefined.

This makes it impossible to test code which handles multiple routes and checks for the incoming request.

ghost avatar Jan 24 '18 14:01 ghost

Also, the networkError() and timeout() methods don't include the request object in the resulting Error object. I have some error handling code that inspects the request, but can't test the error handlers with the mocks enabled.

b4hand avatar Jan 30 '18 23:01 b4hand

Any workaround for this error?

anjapadu avatar Mar 20 '18 13:03 anjapadu

The response.request is the object that axios used to make the actual request. Since the mock doesn't actually make the request, there is no object to return.

As a workaround, could you refactor your code to use response.config? Can you share an example of how your code is using response.request?

JoshMcguigan avatar Mar 30 '18 03:03 JoshMcguigan

As a workaround, could you refactor your code to use response.config?

@JoshMcguigan That doesn't work for us.

Can you share an example of how your code is using response.request?

We are making an Ajax request which redirects on success. Then we need to grab the new URL and make the browser follow it:

axios.get(`${gl.TEST_HOST}/test`)
  .then(response => {
    location.href = response.request.responseURL;
  });

In the long term we will probably get rid of the redirection and pass the target URL as parameter to the component. In the short term it would still be nice to be able to test this. 😃

ghost avatar Mar 30 '18 18:03 ghost

@gitlab-winnie That is an interesting use case. The only way I can imagine this working would be to allow setting the response.request when setting up the mock.

I could see allowing this as a fourth argument to the reply function, as shown below, but it does feel a bit awkward. It would be especially problematic if axios added additional fields to their response object.

// Mock any GET request to /users
// arguments for reply are (status, data, headers, request)
mock.onGet('/users').reply(config=>[200, {data: 'data'}, null, {responseURL: 'google.com'}]);

@ctimmerm Any thoughts on this? I'd be happy to try coding it up if this is something you'd want to include, but I'm not sure I see a clean way to extend the API to include this at the moment.

JoshMcguigan avatar Mar 30 '18 22:03 JoshMcguigan

FWIW, I have the same need, in that I need access to the request object after redirects. While awkward, I would be fine with the response object being a fourth argument, as noted.

csepulv avatar Apr 17 '18 07:04 csepulv

I had a similar issue, and I've fixed it for my tests by adding an extra Interceptor to Axios as a workaround:

axios.interceptors.response.use(res => ({ ...res, request: res.request || res.config }));

This will define a request in the main response, so any code that is in the axios.get().then(...) will have the request defined and the same as config 🎉

It will "polyfill" the .request if it doesn't find it with the config, so feel free to put it wherever you want (though I'd recommend to put it in your tests or test setup).

franciscop-sc avatar May 17 '19 07:05 franciscop-sc