🕥

Jestで時間に依存する処理のテストを書く

2023/07/06に公開

useFakeTimersを使う

useFakeTimersを使うことでモックすることが出来ます。

同期関数のテストをする場合

シンプルにuseFakeTimersを使い、setSystemTimeで時刻を指定すればOK

const testDate = new Date('1999-07-01T12:00:00')

describe('[同期処理]時間に関するテスト', () => {

  it('testDateは現在時刻より前', () => {
    jest.useFakeTimers().setSystemTime(new Date('2025-07-01T12:00:00'))
    expect(testDate.getTime()).toBeLessThan(new Date().getTime())
  })

  it('testDateは現在時刻より後', () => {
    jest.useFakeTimers().setSystemTime(new Date('1998-07-01T12:00:00'))
    expect(testDate.getTime()).toBeGreaterThan(new Date().getTime())
  })
})

非同期関数のテストをする場合

useFakeTimersに何も指定しないとテストを動作させるために必要な値もモックされてしまいテストが動かなくなることがよくあります。
doNotFakeにモックしない値を指定すればOK

import axios from 'axios'

const asyncFunction = async () => {
  try {
    const response = await axios.get('https://zipcloud.ibsnet.co.jp/api/search', {
      params: {
        zipcode: '7830060',
      },
      headers: {
        'Content-Type': 'application/json',
      },
    })
    console.log(response)
  } catch (error) {
    console.error('Error:', error)
  }
}

const testDate = new Date('1999-07-08T12:00:00')

describe('[非同期処理]時間に関するテスト', () => {
  it('非同期関数を呼ぶ場合', async () => {
    jest.useFakeTimers({ doNotFake: ['nextTick'] }).setSystemTime(new Date('2023-07-01T12:00:00'))
    await asyncFunction()

    expect(testDate.getTime()).toBeLessThan(new Date().getTime())
  })

  it('setTimeoutを使っている場合', async () => {
    jest.useFakeTimers({ doNotFake: ['setTimeout'] }).setSystemTime(new Date('2023-07-01T12:00:00'))
    await new Promise(resolve => setTimeout(resolve, 100))

    expect(testDate.getTime()).toBeLessThan(new Date().getTime())
  })
})

注意点

コミューン株式会社

Discussion