Stubbing window.location in JavaScript

6 February 2013

Let's imagine you have the following code:

var el = document.getElementById("some-container");
el.addEventListener('click', handleClick, false);
function handleClick(e) {
var link = e.target.getElementsByTagName('a')[0]
if(link) {
if(e.metaKey) {
return window.open(link.href);
}
window.location = link.href;
}
}

How do I test this?

Short answer: You don't. The reason is that the browser will not allow you to override anything in the window host object.

Long answer: Your best bet is to abstract any 'window' related logic into your own methods. For example, let's create a redirect helper method:

function redirect(path, _blank) {
if(path) {
if(_blank) {
return window.open(path);
}
return window.location = path;
}
}

Now let's utilize this method to simplify the handleClick method.

function handleClick(e) {
var link = e.target.getElementsByTagName('a')[0]
if(link) {
redirect(link.href, e.metaKey);
}
}

Stub it all

Testing it will now be possible by stubbing out our redirect method. I'm using Sinon.js here, a library that provides excellent tooling for stubs.

sinon.stub(window, 'redirect');
// Create a fixture
var div = document.createElement('div');
div.innerHTML = '<a href="#hello">Hello</a>';
// Override event object
var e = {
target : div,
metaKey: false
};
// Call our method
handleClick(e);
// Assert
stub.calledWith('#hello', false); // === true

That's all folks. Happy testing!

Photo of me

Hi, thanks for reading!

Iā€™m Daniel, Software Engineer from Sweden. If you have any questions regarding this article please reach out to me on Bluesky. You can also find me on GitHub.

Read more articles written by me: