🕥
Jestで時間に依存する処理のテストを書く
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())
})
})
注意点
- useFakeTimersはuseRealTimersを呼ぶまでファイル内全てのテストで有効になるので、意図せず他のテストに影響を与えないように注意しましょう。
Discussion