We use cookies on this site to enhance your user experience

By clicking the Accept button, you agree to us doing so. More info on our cookie policy

Mocking window.location in Jest

Published: Jun 18, 2022 by C.S. Rhymes

Recently I had to write some tests for a piece of JavaScript code that used window.location. This left me trying to figure out how to mock the window.location so that I could pass in dummy data and ensure that the data I got back was what was expected. Here was how I managed to solve the issue.

I found a few different articles about mocking but some said they only worked in older versions of jest so I had to find a more up to date solution. There were also some packages that give this functionality, but I proffered to try and work it out without a package.

Make a new Object

In the end it turns out the simplest way was to delete it and make it as a new object, thanks to this post on Stack Overflow.

delete global.window.location;
global.window = Object.create(window);
global.window.location = {};

Using typescript in the test helped me see what keys were required in my location object, so I added all of these in and passed in some dummy values that I could use in my tests.

global.window.location = {
    ancestorOrigins: null,
    hash: null,
    host: 'dummy.com',
    port: '80',
    protocol: 'http:',
    hostname: 'dummy.com',
    href: 'http://dummy.com?page=1&name=testing',
    origin: 'http://dummy.com',
    pathname: null,
    search: null,
    assign: null,
    reload: null,
    replace: null,
};

Now I could set some data in the initial mock and know what the initial state should be and what the end result should be.

Before Each

As this was quite a lot of setup code I decided to move this into a beforeEach() method so it will be run before each test.

This also helps ensure each test isn’t affected by any previous tests which could cause anomalous results.

Now, when I want a different initial state in a test, I can just overwrite the part that needs updating for that test instead of overwriting everything.

describe('removeValueFromParam', () => {
    it('removes a specific value from a given param', () => {
        // Overwrite the default href for this test
        window.location.href = 'http://dummy.com/?page=1&name=testing%2Ctest';

        removeValueFromParam('name', 'testing');

        expect(window.location.href).toEqual('http://dummy.com/?page=1&name=test')
    });
});

To string

The tests kept failing on certain tests. I realised it was failing when the window.location was coming back as undefined instead of a string. Somewhere in the code it was calling window.location.toString() but the mock I had created didn’t have this method.

To match this functionality, I then added a toString() method to my mock. I could hard code a response and make a specific test pass.

// Mock window.location
global.window.location = {
    href: 'http://dummy.com?page=1&name=testing',
    /*
    * Other settings
    */
    toString: () => {
        return 'http://dummy.com?page=1&name=testing';
    },
};

The issue now was that different tests needed different responses from the toString() method, so I decided to look up what the standard method does.

The toString() stringifier method of the Location interface returns a string containing the whole URL. It is a read-only version of Location.href.

Therefore, I just needed to return the location.href to match the default behaviour.

// Mock window.location
global.window.location = {
    href: 'http://dummy.com?page=1&name=testing',
    /*
    * Other settings
    */
    toString: () => {
        return global.window.location.href;
    },
};

Now, the tests were all passing. If your code makes use of other methods in window.location then you should be able to add these to your mock too.

Photo by The Building Envelope on StockSnap

JavaScript Jest Testing

Latest Posts

Fixing a few SEO issues with my author website
Fixing a few SEO issues with my author website

When I launched my cozy mystery series, The Little-Astwick Mysteries, I decided to create a new website to promote it. But I made a few mistakes with SEO that have led to a few issues with Search Engine Optimisation (SEO). Here is how I fixed them.

Using Tailwindcss with Codepen
Using Tailwindcss with Codepen

I created a free account for Codepen to provide a demo with my blog post about ‘Creating a custom toggle in TailwindCSS’ but it took me a little while to figure out how to use Tailwindcss with codepen. So, this is what I did to get it working.

Creating a custom toggle in TailwindCSS
Creating a custom toggle in TailwindCSS

I’ve only just started using TailwindCSS, (I know late to the party huh), and I wanted to create a custom toggle switch that looked a bit nicer than a standard checkbox. This blog post goes through some of the thought processes and the tools that Tailwindcss v4 has out of the box that you can make use of.

How NOT to make a website

Unlooked for Tales - a collection of short stories

By C.S. Rhymes

Free on Apple Books and Google Play Books

Nigel's Intranet Adventure

Nigel's Intranet Adventure

By C.S. Rhymes

From £0.99 or read for free on Kindle Unlimited!