jameslnewell / xhr-mock

Utility for mocking XMLHttpRequest.
196 stars 48 forks source link

Send real request when url not registered #11

Closed jcubic closed 7 years ago

jcubic commented 8 years ago

It would be nice if XHRMock run normal request when someone open url that's not mocked.

jameslnewell commented 8 years ago

Sounds like an interesting feature. Feel free to submit a PR.

AlehVasilyeu commented 7 years ago

I started work on this implementation. I hope I will complete it soon.

jameslnewell commented 7 years ago

Cool!

Please keep in mind that people use this package in the browser AND in nodejs.

Is there a way to make this feature optional because it might not be a feature that everyone would use. Maybe you could write a sharable handler that people can require and reuse. That way we don't force the extra dependencies on axios|superagent|fetch|whatever on the users who don't need this feature.

E.g.

const xhrMock = require('xhr-mock');
const xhrMockProxyHandler = require('xhr-mock-proxy-handler');

xhrMock.setup();

xhrMock
  .get('/my-handled-url', ...);
  .mock(xhrMockProxyHandler)
;

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {

    //when you're finished put the real XHR object back
    xhrMock.teardown();

  }
}

Note: for this to work you'll probably need to finish the final blockers for https://github.com/jameslnewell/xhr-mock/pull/10 so you can return a promise from the handler.

AlehVasilyeu commented 7 years ago

@jameslnewell Sound good, but I'm a little bit confused.

Currently I'm using decorator pattern, so real XMLHttpRequest creates together with mock. I agrre your approach much better, but I have no idea how to pass invocations of methods (like getResponseHeader, addEventListener) to handler. Do you have any suggestions?

jameslnewell commented 7 years ago

xhr-mock-proxy-handler would look something like this (not handling error cases for brevity):

const axios = require('axios');

module.exports = function(req, res) {
  return axios.request({
    method: req.method(), 
    url: req.url(), 
    headers: req.headers(), 
    data: req.body()
  })
    .then(r => {
      return res
        .status(r.statusCode)
        .headers(r.headers)
        .body(r.text)
      ;
    })
  ; 
}

Note: for handlers to return promises like the above handler is dependent on requires #10 being completed.

AlehVasilyeu commented 7 years ago

Thanks for direction, will think.

jameslnewell commented 7 years ago

Mock handlers can now return a Promise and the desired functionality can be implemented in xhr-mock@next.

jameslnewell commented 6 years ago

xhr-mock@2.0.0-preview.11 has a built-in proxy handler. See the docs here.