Mock window.location in Jest

Mocking or writing over global objects in Jest might result in side effects that stays throughout the tests that are run from the same file.

In other words, test A might addEventListener to the window object and test B will be affected with the same event listeners. Here's how to safely writing over global objects in Jest through beforeEach.

describe("Module", () => {
  const { location } = window;
  beforeAll(() => {
    delete window.location;
    window.location = {};

    Object.defineProperty(window.location, "href", {
      get: getHref,
      set: setHref,
    });
  });

  afterAll(() => {
    window.location = location;
  });

  it("redirects to another URL", () => {
    window.location.href = "https://jonas.arnklint.com";
    expect(setHref).toHaveBeenCalledWith("https://jonas.arnklint.com");
    expect(getHref).not.toHaveBeenCalled();
  });

  it("reads from window.location", () => {
    console.log(window.location.href);
    expect(getHref).toHaveBeenCalled();
  });
});

I'm currently working on the Hotlight, a command palette for the web. Much like Spotlight or Albert. Basically I want to build a tool for anyone to offer their users a great simple way to navigate their web app or site. Please follow along if you wish to learn more snippets like the one above!