Jestでwindowオブジェクトをモックする方法

この記事では以下の Window.js と CheckHostName.js を使用します。

export const getHostName = () => {
  return window.location.hostname;
};
import * as Window from "./Window";

export const isTwitter = () => {
  return window.location.hostname === "twitter.com";
};

export const isTwitterCallWrapperFunction = () => {
  return Window.getHostName() === "twitter.com";
};

Windowモジュールをモックする

windowオブジェクトのプロパティの値を返す関数を作ってモックする。

import { isTwitterCallWrapperFunction } from "./CheckHostname";
import * as Window from "./Window";

describe("Windowモジュールをモックする", () => {
  it("ホスト名が「twitter.com」のとき、isTwitterCallWrapperFunction が true を返す", () => {
    const expectedHostName = "twitter.com";
    Window.getHostName = jest.fn().mockReturnValue(expectedHostName);
    expect(isTwitterCallWrapperFunction()).toBe(true);
  });

  it("ホスト名が「twitter.com」以外のとき、isTwitterCallWrapperFunction が falseを返す", () => {
    const expectedHostName = "google.com";
    Window.getHostName = jest.fn().mockReturnValue(expectedHostName);
    expect(isTwitterCallWrapperFunction()).toBe(false);
  });
});

windowオブジェクトのプロパティを上書きする

defineProperty でモック関数を返すようにする。

import { isTwitter } from "./CheckHostname";

describe("windowオブジェクトのプロパティを上書きする", () => {
  const tmpLocation = window.location;

  afterAll(() => {
    Object.defineProperty(window, "location", {
      get: () => {
        return tmpLocation;
      },
    });
  });

  it("ホスト名が「twitter.com」のとき、isTwitter が true を返す", () => {
    const expectedHostName = "twitter.com";
    Object.defineProperty(window, "location", {
      get: jest.fn().mockReturnValue({ hostname: expectedHostName }),
    });
    expect(isTwitter()).toBe(true);
  });

  it("ホスト名が「twitter.com」以外のとき、isTwitter が falseを返す", () => {
    const expectedHostName = "google.com";
    Object.defineProperty(window, "location", {
      get: jest.fn().mockReturnValue({ hostname: expectedHostName }),
    });
    expect(isTwitter()).toBe(false);
  });
});

windowオブジェクトをspyする

Jest の spyOn を使う。

import { isTwitter } from "./CheckHostname";

describe("windowオブジェクトをspyする", () => {
  it("ホスト名が「twitter.com」のとき、isTwitter が true を返す", () => {
    const expectedHostName = "twitter.com";
    const originalWindow = { ...window };
    const windowSpy = jest.spyOn(global, "window", "get");
    windowSpy.mockImplementation(() => ({
      ...originalWindow,
      location: {
        ...originalWindow.location,
        hostname: expectedHostName,
      },
    }));
    expect(isTwitter()).toBe(true);
  });

  it("ホスト名が「twitter.com」以外のとき、isTwitter が falseを返す", () => {
    const expectedHostName = "google.com";
    const originalWindow = { ...window };
    const windowSpy = jest.spyOn(global, "window", "get");
    windowSpy.mockImplementation(() => ({
      ...originalWindow,
      location: {
        ...originalWindow.location,
        hostname: expectedHostName,
      },
    }));
    expect(isTwitter()).toBe(false);
  });
});