16
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Jest】非同期コードのテストの3つの書き方

Posted at

Jest の非同期コードのテストの書き方は大きく分けて3つある。

3つのテスト方法

  1. done
  2. expect.assertions + return Promise
  3. 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')
})

参考

16
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?