How to mock window.location.href with Jest + Vuejs?
Solution 1
You can try:
global.window = Object.create(window);
const url = "http://dummy.com";
Object.defineProperty(window, 'location', {
value: {
href: url
}
});
expect(window.location.href).toEqual(url);
Have a look at the Jest Issue for that problem:
Jest Issue
Solution 2
2020 Update
Basic
The URL object has a lot of the same functionality as the Location object. In other words, it includes properties such as pathname
, search
, hostname
, etc. So for most cases, you can do the following:
delete window.location
window.location = new URL('https://www.example.com')
Advanced
You can also mock Location methods that you might need, which don't exist on the URL interface:
const location = new URL('https://www.example.com')
location.assign = jest.fn()
location.replace = jest.fn()
location.reload = jest.fn()
delete window.location
window.location = location
Solution 3
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
});
Solution 4
Solution for 2019 from GitHub:
delete global.window.location; global.window = Object.create(window); global.window.location = { port: '123', protocol: 'http:', hostname: 'localhost', };
Solution 5
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");
});
Comments
-
Tran Son Hoang over 2 years
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 my sample code:
it("method A should work correctly", () => { const url = "http://dummy.com"; Object.defineProperty(window.location, "href", { value: url, writable: true }); const data = { id: "123", name: null }; window.location.href = url; wrapper.vm.methodA(data); expect(window.location.href).toEqual(url); });
But I get this error:
TypeError: Cannot redefine property: href at Function.defineProperty (<anonymous>)
I had tried some solutions but not resolve it. I need some hints to help me get out of this trouble. Plz help.
-
Jay over 4 yearsThis solution also works for overwriting
window.location.hostname
in Jest tests. I neededwritable: true
in order to change thehostname
more than once. -
peter.swallow over 4 yearsThis is the only one that seems to work for me and with a helpful reason why! :)
-
Md. Amanullah over 4 yearsthis helps me a lot
-
dshun over 3 yearswith typescript update,
delete window.location
will trigger an errorThe operand of a 'delete' operator must be optional
-
Sujith over 3 years@dhsun any solution to the problem you have mentioned above? I am facing similar issue
-
xbmono over 3 years
writable: true
was necessary for my unit tests to work otherwise the subsequent tests wouldn't be able to overwrite it to something else. Thanks -
xbmono over 3 yearsFor me using
global
didn't work, I removedglobal.
and I also needed to addwritable: true
otherwise once set the other tests can't change it. -
Tom over 3 yearsAdd // @ts-ignore above the line delete window.location; if you must
-
wlh about 3 yearsI wonder if it shouldn't be
const realLocation = Object.assign({}, window.location);
since I feel just assigning it directly would be passing a reference which is later overwritten. Thoughts? -
Washington Guedes almost 3 yearsIt works, but breaks following tests using postMessage that needs the original
location.host
property -
JCQuintas almost 3 years
Reflect.deleteProperty(global.window, 'location')
deals with that without ts error -
Mustafa almost 3 yearsTo get around that TS error you can do
delete (window as any).location;
-
RobW almost 3 yearsThe object that the original window.location points to is not mutated in this code -- the window.location property has different objects set inside it. Since there's no mutation of the original window object, there's no need to clone it.
-
Quoting Eddie over 2 yearsThere is another, seldomly used, property on the Location API:
ancestorOrigins
. You might want to mock that, too. -
Enes Kirimi over 2 yearsThis is what I was looking for. Best solution for me.
-
Mohammad Kermani about 2 yearsWhy the
window.location
should be deleted? Can't it override it bywindow.location = location
only?