-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider moving XHR/XDR aliases inside createXHR() #11
Comments
unit testing is trivial var xhr = require("xhr")
var myController = function (opts) {
var request = opts.request || xhr
return { fetchStuff: function () { ... } }
} globally punching
|
Ah now :) We could argue about where exactly the faking/mocking should happen for daaaays :) Just like about how much should the tests be integration vs unit... I'm not sure that creating an alias of a global object, that one does not control, and behaves, essentially, like a private static property, is the right solution either (but I hate singletons in general). I must admit, that I have a promise wrapper around the thing, so it will have to be tomorrow before I try it. It would probably break semver, but passing in a constructor function, rather than the constructed object seems somewhat more appropriate to me right now, but I might change my mind in the morning :) |
Let me know if it works for you. |
Yeah, this does the trick, although I will end up basically re-implementing the whole "if cors xdr else xhr" thing and then still hijack the global XHR with sinon's fakeServer - creating a fake object and reimplementing the whole API just for tests would be too much of a hassle. Any reasons not to move the aliases inside the exported function? |
They are my top level dependencies. Having them change out from underneath me is not something I want, whether for good (testing) or for bad (lol new magic xmlhttprequest). It just seems like a complete hack. |
But you can't rely on them not having been changed before the module is even require()d... So, considering that you already assume that the XHR is the XHR (with correct interface, etc) - are there any other benefits the current approach brings? |
Closing this issue. I think this is solved, if you have any other concerns let me know |
I realize it is closed, but I'd like to add a +1 to this issue. Trying to test with jasmine-ajax on my end and it is very clunky to have to pass the stubbed XHR in just for testing. @dominykas is right, you can't be certain anyway that the XHR is the one you want if it's changed before it's required. |
You can pass Does this solve your issue? |
So yes, technically I can do what you suggested, just as I'm sure the OP could. It just makes it difficult for testing. Just some background, I'm using the ampersand project which uses xhr as a dependency for fetching models. Normally I just call Beyond my own problems though, I would think that this library would want to be compatible with major ajax testing libraries like jasmine-ajax and sinon and work out of the box. I understand the concern that it can be hacked and used improperly, but I'm not sure using anything that is passed in is better and doesn't really prevent hijacking from happening anyway if XHR is replaced before the library is required. Regardless, I wanted to say thanks for all the work on the library! |
@mmacaula I disagree with that approach of testing. Anything that manipulates globals is not something that will always work. My best recommendation for you is to monkey patch globals first before importing the ampersand or xhr library. |
That won't work for me unfortunately. The way jasmine ajax works, you monkey patch before your test, and reverse it afterwards and by then it's too late. I have other tests in the suite that have already required xhr. So if that's out, would you be amenable to other approaches that could help me out? Say, providing a way to configure the library to use a different constructor rather than having to pass an instance? something like: require('xhr').configure('XHRConstructor', defaultConstructor); // or something else like a fake one? Beyond the uses for testing, this could be helpful for globally configuring xhr to have certain fields defaulted. |
@mmacaula I think your suggestion is reasonable. require('xhr').set({
XHR: function () { ... },
XDR: function () { ... }
}) |
Glad to hear it, would you like me to create a new issue for that? |
@mmacaula sure :) |
Having these two lines outside of the main exporter function means, that the aliases are created before the module is required:
And since the aliases are already created, it is impossible to stub/mock XMLHttpRequest with e.g. http://sinonjs.org/docs/#server Considering that it is also impossible to fake out the exported function itself, it becomes practically impossible to properly unit test anything that uses the xhr module without having an actual HTTP server, which is not always feasible.
If the above two lines were inside createXHR() - we could hijack/fake XMLHttpRequest before calling the exported function. Aside from negligible performance impact, I don't really see any good reason not to do so - does one exist?
The text was updated successfully, but these errors were encountered: