はじめに
Jestについて学習したことを整理して備忘録としてまとめました。
学習内容
Jestの特徴
- 設定がほとんど不要で導入が簡単
- 依存関係のモック化が簡単
- スナップショットテストが簡単
- 並列テストで高速なテスト
- カバレッジレポート
- 柔軟なマッチャー
インストールと設定
$ npm install --save-dev jest
--save-dev
は、開発環境用のインストールであることを表す。
デフォルトのpackage.json
の"scripts"内の"test"の値を"jest"にする。
マッチャー
jestにおける一般的なマッチャーの例(toBe()
は厳密等価)
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
なお、toBe
の前に.not
をはさむと、逆をテストできる。
その他の例は次のとおり。
-
toBeNull
は null のみ一致 -
toBeUndefined
は undefined のみ一致 -
toBeDefined
は toBeUndefined の反対です -
toBeTruthy
は if ステートメントが真であるとみなすものに一致 -
toBeFalsy
は if ステートメントが偽であるとみなすものに一致 - 数値の比較は、数学記号に対応するマッチャーが用意されている。例|
toBeGreaterThanOrEqual
など - 文字列では、正規表現でマッチできる。マッチャーは、
toMatch
- 配列などに、ある要素が含まれるかどうかをテストするには、
toContain
を使う - ある関数が呼び出し時に例外を投げることをテストするには、
toThrow
を用いる。このとき、テスト対象の関数は、ラムダ関数でラッピングしなければならない。 例|expect(() => targetThrowExcept()).toThrow
非同期処理のテスト
Async/Await
Jestで非同期関数をテストするには、Async/Awaitが便利。testに渡す関数にasync
を付け、非同期処理をawait
で待ってからexpect
。await
しないと、処理完了前にテストが進行するので注意。
Promise
Jestで非同期処理をPromiseでテストするなら、Promiseをreturnし、メソッドチェーン内でexpectを実行。Promiseがrejectされるとテストは失敗。
expect
の後にresolve
マッチャーを付けた上でpromiseをreturnすれば、promiseが解決することをテストできる。rejectも同様。
### コールバック
非同期処理のコールバックテストは、test
にdone
を渡して、expect
後にdone()
を呼ぶ。エラー時はdone(error)
をcatch
で処理。
アサーションの確認
expect.assertions(number)
で、特定の回数だけアサーションが実行されたかを確認。非同期コードのテストで、ちゃんとアサーションが呼ばれたかチェックするのに便利。
モック関数
モック関数の作成とテスト実行
jest.fn(callback)
でモック関数作成。mockプロパティで呼び出し時のデータや返り値が確認でき、関数の動作を詳細に追える。モック関数を使ってテスト対象を実行し、モック関数のmockプロパティをexpectでチェック。コールバックが期待通り呼ばれているかをテストできる。
戻り値の注入
モック関数は、テスト用の値注入にも便利。モック関数(引数無し)を作成し、そのmockReturnValueOnce
をメソッドチェーンで繋げば、モック関数を呼び出すごとにメソッドチェーンの順で指定した値を返す。
API利用部分のモック化
APIにアクセスせずにテストするためには、jest.mock()
で例えばaxiosをモックし、mockResolvedValue
を使って任意のデータを返すように設定可。これにより、axios.get('/users.json')
などの呼び出しに対して偽(仮)のレスポンスを返すことが可能。
実装のモック化
特定の値を返すだけでなく、実装自体をモックしたい場合は、jest.fn
やモック関数のmockImplementationOnce
メソッドを使えば実現できる。
mockImplementation
はモック関数のデフォルト実装を設定することが可能。
呼び出しごとに異なる結果を返したい場合はmockImplementationOnce
を使用する。
実装が尽きた場合、jest.fn
のデフォルト実装が実行される。
モジュールのモック化
jest.mock()
の引数にモジュール名を渡すと、モジュール全体をモック化できる。
Jestの詳細設定
Jestの詳細な設定は、jest.config.js|ts|mjs|cjs|jsonといったファイルで定義するのが推奨されており、これらのファイルは自動的に検出される。設定はオブジェクトとしてエクスポートする。
testEnvironment
はJestのテスト実行環境を設定するオプション。デフォルトはNode.js環境だが、フロントエンドのテストにはjsdomを使ってブラウザに近い環境で実行できる。
setupFiles
とsetupFilesAfterEnv
は、Jestでテストを実行する前に特定の設定や処理を行うための設定。jest.config.jsで、テスト前に実行するファイルを指定できる。
テストカバレッジ
アプリのテストカバレッジを見るにはコンソールで以下コマンドを実行する。
npm test --coverage
coverage/
というディレクトリが生成され、index.htmlに、わかりやすくテストサマリが表示される。
describe
describe
は、関連するテストを1つのブロックにまとめるためのメソッドで、その中に関連するテストケースを記述する。
スナップショットテスト
Jestのスナップショットテストは、テスト対象の出力(UIコンポーネントやオブジェクトの構造、簡単に言うとHTML)を保存し、後のテストでその出力がスナップショットと一致しているか確認する手法。
expect(UIコンポーネント).toMatchSnapshot();
と実行すると、スナップショットファイルが作成され、以降はこのスナップショットと比較される。不一致ならばテスト失敗。意図的な更新ならば、jest --updateSnapshot
で更新可。テストファイル内にスナップショットを記述する(インライン)こともできる
カスタムマッチャー
カスタムマッチャーは、expect().extend()
に関数をオブジェクトに包んでから渡して(つまり、expect().extend({関数})とする。)作成する。その関数内で条件判定のロジックを書き、最後にmessage
とpass
をキーに持つオブジェクトを返す。pass
の真偽値がテスト結果となる。
テストを実行する際は、expect().カスタムマッチャー()
と呼び出す。
参考文献