Let’s say I have a utility function that, for simplicity’s sake (the real thing is complicated and irrelevant), returns the current window’s querystring.
var someUtilityFunction = () {
return window.location.search.substring(1);
};
Now I want to unit test this function in qUnit (not sure if the testing harness is relevant or not):
test('#1 someUtilityFunction works', function () {
// setup
var oldQS = window.location.search;
window.location.search = '?key1=value1&key2=value2&key3=value3';
var expectedOutput = 'key1=value1&key2=value2&key3=value3';
// test
equals(someUtilityFunction(),
expectedOutput,
'someUtilityFunction works as expected.');
// teardown
window.location.search = oldQS;
});
The problem here is that setting the window.location.search to a different querystring is causing the page to reload, essentially entering an infinite request loop. Is there any way to mock out the window.location object without making any changes to the someUtilityFunction function?
We run into the same problem a few days ago. Mainly there are 2 approaches:
Rewrite your code
This might not be the best (if any) solution, but consider passing the
windowobject to your function to make mocking easier. Even better, use a closure and encapsulate your code. This has a few more advantages:Wrap your code
You can wrap all your code inside a function which mocks the window object into a local variable. You have basically two possibilities there as well:
Suppose this is the mock:
Use a closure
This shadows the global
windowwith a localwindow.Use the
withstatementAlthough I am usually strongly against with, it could really solve a lot of problems here. Since it basically remaps your scope, you can very easily mock your environment.
By the way: I don’t know if the
searchproperty suffers from the same symptoms as thehashproperty – namely sometimes including the question mark and sometimes not. But you might want to consider usinginstead of