概要

Vue コンポーネントのユニットテストで日時を特定の時点に設定してテストを実行したいときがあります。
Jest のモック関数である SpyOn を使って任意の時間をシミュレートする方法を書いています。

テスト対象のコンポーネント

まずはテストを書く対象となるコンポーネントを用意します。
現在時刻が午前か午後かによって表示されるテキストが変化します。

<template>
  <div>{{ morning ? '午前だよ' : '午後だよ' }}</div>
</template>

<script>
  export default {
    computed: {
      morning() {
        return new Date().getHours() < 12;
      },
    },
  };
</script>

jest.spyOn() で Date 関数をモックする

次にテストを書きます。

まず、spyOn 関数でグローバルオブジェクトの Date 関数をモック化します。
そして mockImplementation によって元の関数を上書きして mockDate を返すようにしています。

これでテスト実行中は new Date を実行すると mockDate が返ってくるようになります。
日時が固定できるようになり、テストの実行時刻によって結果が変わることがなくなりました。

import { shallowMount } from "@vue/test-utils";
import TestDate from "@/components/TestDate";

describe("TestDate", () => {
  test('現在時刻が午前中であれば "午前だよ" が表示される', () => {
    const mockDate = new Date(2020, 1, 1, 2);
    jest.spyOn(global, "Date").mockImplementation(() => mockDate);

    const wrapper = shallowMount(TestDate);
    expect(wrapper.text()).toBe("午前だよ");
  });
});