In a recent project, I needed to write a test for a React component that redirects. 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 (bundled with Jest 24.9.0) does not like this code and throws an error: “Not implemented: navigation (except hash changes),” which makes the test fail.
Previously (back in 2018, I think), it was possible to fix this with code like this:
Object.defineProperty(window.location, 'href', {
writable: true,
value: ''
});
Alas, for jsdom >= 14, this no longer works. One solution was to redefine the window object entirely, then use Object.defineProperty() to redefine the 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