How to mock window.location.href with Jest + Vuejs?

泪湿孤枕 提交于 2020-03-17 05:35:04

问题


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.


回答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




回答2:


Solution for 2019 from GitHub:

delete global.window.location;
global.window = Object.create(window);
global.window.location = {
  port: '123',
  protocol: 'http:',
  hostname: 'localhost',
};



回答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
});



回答4:


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




回答5:


Can rewrite window.location by delete this global in every test.

delete global.window.location;
const href = 'http://localhost:3000';
global.window.location = { href };



回答6:


Many of the examples provided doesn't mock the properties of the original Location object.

What I do is just replace Location object (window.location) by URL, because URL contains the same properties as Location object like "href", "search", "hash", "host".

Setters and Getters also work exactly like the Location object.

Example:

const realLocation = window.location;

describe('My test', () => {

    afterEach(() => {
        window.location = realLocation;
    });

    test('My test func', () => {

        // @ts-ignore
        delete window.location;

        // @ts-ignore
        window.location = new URL('http://google.com');

        console.log(window.location.href);

        // ...
    });
});



回答7:


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


来源:https://stackoverflow.com/questions/54021037/how-to-mock-window-location-href-with-jest-vuejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!