Jest の非同期コードのテストの書き方は大きく分けて3つある。
3つのテスト方法
done
-
expect.assertions
+ return Promise -
expect.assertions
+ async/await
1. done
テストを記述する関数の第一引数の done
を使用し、テストが全て終了したら done()
を呼ぶ。
Jest は done
が呼ばれるまで待機する。
done
が呼ばれなかった場合はテストは失敗する。
// コールバックが呼ばれることを期待するケース
it('the data is peanut butter', done => {
function callback(data) {
expect(data).toBe('peanut butter')
done()
}
fetchData(callback)
})
2. expect.assertions
+ return Promise
テストを記述する関数で Promise を返す。
Jest は Promise が解決されるまで待機する。
expect.assertions
を追加し、想定した数のアサーションが呼ばれることをチェックしなければならない。
// resolve されることを期待するケース
it('the data is peanut butter', () => {
expect.assertions(1)
return fetchData()
.then(data => {
expect(data).toBe('peanut butter')
})
})
// reject されることを期待するケース
it('the fetch fails with an error', () => {
expect.assertions(1)
return fetchData()
.catch(e => {
expect(e).toMath('error')
})
})
3. expect.assertions
+ async/await
テストを記述する関数で async/await を使う。
Jest は Promise が解決されるまで待機する。
expect.assertions
を追加し、想定した数のアサーションが呼ばれることをチェックしなければならない。
// resolve されることを期待するケース
it('the data is peanut butter', async () => {
expect.assertions(1)
const data = await fetchData()
expect(data).toBe('peanut butter')
})
// reject されることを期待するケース
it('the fetch fails with an error', () => {
expect.assertions(1)
try {
await fetchData()
} catch (e) {
expect(e).toMatch('error')
}
})
各方法の使い分け
テスト対象がコールバック関数を引数にとる関数の場合は、done
を使う方法を使用する。
テスト対象が Promise を返す関数の場合は return Promise の方法、または async/await を使う方法を使用する。
番外編: .resolves
, .rejects
マッチャ
単に特定の値で解決されることをテストする場合、.resolves
, .rejects
マッチャを使うと簡潔に書ける。
Jest は Promise が解決されるまで待機する。
// resolve されることを期待するケース
it('the data is peanut butter', () => {
expect.assertions(1)
return expect(fetchData()).resolves.toBe('peanut butter')
})
// reject されることを期待するケース
it('the fetch fails with an error', () => {
expect.assertions(1)
return expect(fetchData()).rejects.toMatch('error')
})
async/await を使う場合
// resolve されることを期待するケース
it('the data is peanut butter', async () => {
expect.assertions(1)
await expect(fetchData()).resolves.toBe('peanut butter')
})
// reject されることを期待するケース
it('the fetch fails with an error', async () => {
expect.assertions(1)
await expect(fetchData()).rejects.toMatch('error')
})