I am trying to test a simple function that makes a call to window.location.search. I'm trying to understand how to stub this call so that I can return a url of my choosing.
function:
getParameterByName: (name) =>
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]")
regexS = "[\\?&]" + name + "=([^&#]*)"
regex = new RegExp(regexS)
results = regex.exec(window.location.search) //Stub call to window.location.search
if(results == null)
return ""
else
return decodeURIComponent(results[1].replace(/\+/g, " "))
Test case:
describe "Data tests", () ->
it "Should parse parameter from url", () ->
data = new Data()
console.log("search string: " + window.location.search) //prints "search string:"
window.location.search = "myUrl"
console.log("search string: " + window.location.search) //prints "search string:"
console.log(data.getParameterByName('varName'))
expect(true).toBe(true)
My original attempt was to return a value directly like so:
sinon.stub(window.location.search).returns("myUrl")
This, of course, doesn't work. I don't think I'm specifying the stub correctly, but it shows my intent.
Any ideas on how to solve this would be greatly appreciated.
So, as mentioned before, you can't mock window.location directly. Nor did the mylib.search wrapper idea work with my situation. So, what I did was break out my call to window.location.search
into its own function. My new class looks like so:
getParameterByName: (name) =>
console.log("name: #{name}")
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]")
regexS = "[\\?&]" + name + "=([^&#]*)"
regex = new RegExp(regexS)
results = regex.exec(@getWindowLocationSearch())
if(results == null)
return ""
else
return decodeURIComponent(results[1].replace(/\+/g, " "))
getWindowLocationSearch:() =>
window.location.search
Then in my test case, I replace the function with my test code like so:
describe "Data tests", () ->
it "Should parse parameter from localhost url", () ->
goodUrl = "http://localhost:3333/?token=val1"
Data::getWindowLocationSearch = () -> return goodUrl
unit = new Data()
result = unit.getParameterByName("token")
expect(result).toBe("val1")
For those who don't read Coffeescript, the equivalent javascript code is listed below:
it("Should parse parameter from localhost url", function() {
var goodUrl, result, unit;
goodUrl = "http://localhost:3333/?token=val1";
Data.prototype.getWindowLocationSearch = function() {
return goodUrl;
};
unit = new Data();
result = unit.getParameterByName("token");
expect(result).toBe("val1");
return expect(true).toBe(true);
});
As is my usual experience with Javascript. The working solution was not nearly as painful as the journey to get there. Thank you very much for your comments and contributions.
UPDATE: window.location
, it seems, is a bit of a special case, see this discussion: https://groups.google.com/forum/?fromgroups#!topic/sinonjs/MMYrwKIZNUU%5B1-25%5D
The easiest way to solve this problem is to write a wrapper function around window.location
, and stub that:
mylib.search = function (url) {
window.location.search = url;
};
And in your test:
sinon.stub(mylib, 'search').returns("myUrl")
ORIGINAL ANSWER:
Try this:
sinon.stub(window.location, 'search').returns("myUrl")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With