Skip to content

Instantly share code, notes, and snippets.

@remarkablemark
Last active November 14, 2023 08:55
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save remarkablemark/5cb571a13a6635ab89cf2bb47dc004a3 to your computer and use it in GitHub Desktop.
Save remarkablemark/5cb571a13a6635ab89cf2bb47dc004a3 to your computer and use it in GitHub Desktop.
How to mock `window.location.reload` in Jest and jsdom: https://remarkablemark.org/blog/2018/11/17/mock-window-location/
it('mocks window.location.reload', () => {
const { location } = window;
delete window.location;
window.location = { reload: jest.fn() };
expect(window.location.reload).not.toHaveBeenCalled();
window.location.reload();
expect(window.location.reload).toHaveBeenCalled();
window.location = location;
});
{
"scripts": {
"test": "jest"
},
"dependencies": {
"jest": "latest"
}
}
@NachoJusticia
Copy link

Nice!
It worked 👍

Thank you very much for this gist.

@aaronkzhou
Copy link

thanks!

@DanielSWolf
Copy link

👍

@pernilsalat
Copy link

thanks!

@noebrito
Copy link

Gracias!

@joshjg
Copy link

joshjg commented May 2, 2019

No longer works in jsdom 14

TypeError: Cannot redefine property: reload

@joshjg
Copy link

joshjg commented May 2, 2019

I found a workaround for newer versions in the comments here:

delete window.location;
window.location = { reload: jest.fn() };

@remarkablemark
Copy link
Author

Thanks for sharing your workaround for jsdom >=14 @joshjg

I've updated the gist and blog post

@cbrunnkvist
Copy link

(Chrome 77 / Electron 61) Now Cannot delete property 'location' of [object Window] 😞

@satheshrgs
Copy link

satheshrgs commented Jan 10, 2020

Working for Class Components, but not working for modules :(

@Shrikant9
Copy link

Shrikant9 commented Jan 21, 2020

Working in storybooks. Thanks a lot!

@mkonikov
Copy link

Thanks for this!

@fakocher
Copy link

fakocher commented Feb 5, 2020

Thank you 👍

@baskint
Copy link

baskint commented Apr 1, 2020

Thank you as well, updated a few packages and reload started throwing a TypeError as described above. Rewired using this gist. Works like a charm 👍

@ksweetie
Copy link

ksweetie commented Jun 24, 2020

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.

This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

@Yilong94
Copy link

Yilong94 commented Aug 6, 2020

Thank you for this! 👍

@inalbant
Copy link

inalbant commented Aug 25, 2020

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.

This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

With this I get the error: The operand of a 'delete' operator must be optional.

Any ideas on how to fix? I've disabled TS for that line for now for as a temp fix.

@evargast
Copy link

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.
This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

With this I get the error: The operand of a 'delete' operator must be optional.

Any ideas on how to fix? I've disabled TS for that line for now for as a temp fix.

@inalbant You should be able to do

        const reloadSpy = jest.fn();

        Object.defineProperty(window, "location", {
            value: { reload: reloadSpy },
        });

@mehmetnyarar
Copy link

mehmetnyarar commented Sep 29, 2020

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.
This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

With this I get the error: The operand of a 'delete' operator must be optional.

Any ideas on how to fix? I've disabled TS for that line for now for as a temp fix.

Worked for me. (context: Next.js, strict option is disabled by default)

@inalbant
Copy link

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.
This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

With this I get the error: The operand of a 'delete' operator must be optional.
Any ideas on how to fix? I've disabled TS for that line for now for as a temp fix.

@inalbant You should be able to do

        const reloadSpy = jest.fn();

        Object.defineProperty(window, "location", {
            value: { reload: reloadSpy },
        });

Unfortunately, this returns an error:

TypeError: Cannot assign to read only property 'location' of object '#<Window>'

@Carchuli
Copy link

Thanks!
Worked with createObjectURL and revokeObjectURL

@laurenbarker
Copy link

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.
This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

With this I get the error: The operand of a 'delete' operator must be optional.

Any ideas on how to fix? I've disabled TS for that line for now for as a temp fix.

@inalbant, you can use a type assertion:

// Type assertion is used so TypeScript won't complain about
// deleting the required property, `window.location`.
delete (window as Partial<Window>).location;
window.location = { ...window.location, reload: jest.fn() };

@guiworks
Copy link

guiworks commented Feb 3, 2021

Worked perfectly. Congrats!

@brunagarcia
Copy link

Thanks, this whole thread was a lifesaver. :)

@felipeS
Copy link

felipeS commented Aug 11, 2021

I tried this, but I always get the expect to pass even though when the window.location.reload is not called at all, or when expecting toHaveBeenCalledTimes(2)

Has anyone tried to make the test fail?

@Zandy12
Copy link

Zandy12 commented Sep 27, 2021

Thank you! The workaround joshjg provided worked! 🥇

@hyfydistro
Copy link

Thank you! @laurenbarker This worked for me! :D

@hyfydistro
Copy link

How is it this is working when the property is already deleted? (I'm using with TypeScript.)

delete window.location
window.location = { ...window.location, reload: jest.fn() }

@SerhatG35
Copy link

With TypeScript, the above gave me Type '{ reload: Mock<any, any>; }' is missing the following properties from type 'Location': ancestorOrigins, hash, host, hostname, and 8 more.
This worked for me:

delete window.location
window.location = { ...window.location, reload: jest.fn() }

With this I get the error: The operand of a 'delete' operator must be optional.
Any ideas on how to fix? I've disabled TS for that line for now for as a temp fix.

@inalbant, you can use a type assertion:

// Type assertion is used so TypeScript won't complain about
// deleting the required property, `window.location`.
delete (window as Partial<Window>).location;
window.location = { ...window.location, reload: jest.fn() };

Solved my issue, thank you so much 🙏

@Ineyegabriel
Copy link

@laurenbarker You saved my life 🙏

@harrygreen
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment