Jest で時刻などのテストを CI で動かすために時刻を固定化する

Jest でテストを実装している際に、日時、時刻などをモックする事は良くある。 その際のモック内容自体が実行時のマシンのタイムゾーン設定などが違う場合、実行結果も併せて違ってきてしまいテストが失敗してしまう。 それに対する対応をしたのでメモとして残しておきます。

結論

対応としては Jest の設定でタイムゾーンを指定してしまう。jest.config.js などに設定を追加する方法もあるが、ファイルを増やしたくなかったので package.json に設定をする事にした。

{
  ...
  "jest": {
    "globals": {
      "TZ": "utc"
    }
  }
}

テストコード

実際のテストコードはこんな感じでモックしている

describe('Logger: ロガー', () => {
  let now
  let spiedDate

  beforeAll(() => {
    const OriginalDate = Date
    now = new OriginalDate('05 October 2019 14:48 UTC')
    Date.now = jest.fn().mockReturnValue(now.valueOf())
    spiedDate = jest.spyOn(global, 'Date').mockImplementation((arg) => {
      if (arg === 0 || arg) {
        return new OriginalDate(arg)
      }
      return now
    })
  })
  afterAll(() => {
    spiedDate.mockRestore()
  })

  test('now は現在時刻の文字列を返す', () => {
    let log = new Logger()
    expect(log.now).toBe(`[ 2019-10-05T14:48:00.000Z ]`)
  })
})

参考