In a recent project, I needed to write a test for a React component which performed a redirect. Something like this:

useEffect((): void => {
    if (type !== 'in progress') {
        ref.current && ref.current.scrollIntoView();
        if (url) {
            setTimeout((): void => {
                self.top.location.href = url;
            }, 1500);
        }
    }
}, [type]);

jsdom (version bundled with Jest 24.9.0) does not like this code and spits an error: Not implemented: navigation (except hash changes), making the test fail.

Previously (back in 2018, I think), it was possible to fix this with a code like this:

Object.defineProperty(window.location, 'href', {
    writable: true,
    value: ''
});

Alas, for jsdom >= 14 this no longer works. One of the solutions was to redefine window object completely, and then use Object.defineProperty() to redefine location object. However, instead of redefining window it is possible to redefine just location:

delete window.location;
window.location = {
    href: '',
};

The complete solution with Jest may look like this (TypeScript):

describe('location.href', (): void => {
    const { location } = window;

    beforeAll((): void => {
        delete window.location;
        // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
        // @ts-ignore
        window.location = {
            href: '',
        };
    });

    afterAll((): void => {
        window.location = location;
    });

    it('should handle assignments to location.href correctly', (): void => {
        const target = 'https://example.com/';
        window.location.href = target;
        expect(window.location.href).toBe(target);
    });
});
Jest: How to Mock window.location.href
Tagged on:                 

Leave a Reply

Your email address will not be published. Required fields are marked *