Currently, I am implementing unit test for my project and there is a file that contained window.location.href
.
I want to mock this to test and here is m
This is valid for Jest + TypeScript + Next.js (in case you use useRoute().push
const oldWindowLocation = window.location;
beforeAll(() => {
delete window.location;
window.location = { ...oldWindowLocation, assign: jest.fn() };
});
afterAll(() => {
window.location = oldWindowLocation;
});
JSDOM Version
Another method, using JSDOM, which will provide window.location.href
and all of the other properties of window.location
, (e.g. window.location.search
to get query string parameters).
import { JSDOM } from 'jsdom';
...
const { window } = new JSDOM('', {
url: 'https://localhost/?testParam=true'
});
delete global.window;
global.window = Object.create(window);
You can try a helper:
const setURL = url => global.jsdom.reconfigure({url});
describe('Test current location', () => {
test('with GET parameter', () => {
setURL('https://test.com?foo=bar');
// ...your test here
});
});
Based on examples above and in other threads, here is a concrete example using jest
that might help someone:
describe('Location tests', () => {
const originalLocation = window.location;
const mockWindowLocation = (newLocation) => {
delete window.location;
window.location = newLocation;
};
const setLocation = (path) =>
mockWindowLocation(
new URL(`https://example.com${path}`)
);
afterEach(() => {
// Restore window.location to not destroy other tests
mockWindowLocation(originalLocation);
});
it('should mock window.location successfully', () => {
setLocation('/private-path');
expect(window.location.href).toEqual(
`https://example.com/private-path`
);
});
});
I have resolved this issue by adding writable: true
and move it to beforeEach
Here is my sample code:
global.window = Object.create(window);
const url = "http://dummy.com";
Object.defineProperty(window, "location", {
value: {
href: url
},
writable: true
});
The best is probably to create a new URL instance, so that it parses your string like location.href
does, and so it updates all the properties of location
like .hash
, .search
, .protocol
etc.
it("method A should work correctly", () => {
const url = "http://dummy.com/";
Object.defineProperty(window, "location", {
value: new URL(url)
} );
window.location.href = url;
expect(window.location.href).toEqual(url);
window.location.href += "#bar"
expect(window.location.hash).toEqual("#bar");
});
https://repl.it/repls/VoluminousHauntingFunctions