3億年ぶりに JEST を使って引数を取る関数がエラーになる場合のテストケースを書いていてちょいハマったのでメモ
環境
- jest
^27.5.0
- ts-jest
^27.1.3
- typescript
^4.5.5
JEST toThrow(error)
でエラーになる場合のテストができる
toThrow()
に取れる
- 正規表現: エラーメッセージがパターンに マッチする か検証します
- 文字列:エラーメッセージが文字列を含む か検証します
- error オブジェクト: エラーメッセージがオブジェクトのmessageプロパティと等しいかを検証します
- errorクラス: errorオブジェクトがそのクラスのインスタンスであるかを検証します
※ .toThrowError(error?)
は toThrow(error)
のエイリアス
function drinkFlavor(flavor) { if (flavor == 'octopus') { throw new DisgustingFlavorError('yuck, octopus flavor'); } } // test test('throws on octopus', () => { function drinkOctopus() { drinkFlavor('octopus'); } // Test that the error message says "yuck" somewhere: these are equivalent expect(drinkOctopus).toThrowError(/yuck/); expect(drinkOctopus).toThrowError('yuck'); // Test the exact error message expect(drinkOctopus).toThrowError(/^yuck, octopus flavor$/); expect(drinkOctopus).toThrowError(new Error('yuck, octopus flavor')); // Test that we get a DisgustingFlavorError expect(drinkOctopus).toThrowError(DisgustingFlavorError); });
cf. .toThrow(error?) | Expect · Jest
テストする関数は expect
内で実行される必要がある
引数を取る関数のエラーになる場合のテストをしようと下記のように書いて正しくエラーを取ることができなかった。
const myFunc = (data: string[]) => { if (!data.length) { throw new Error('Empty data :('); } }; // test describe('myFunc', () => { test('When argument is an empty array, throw error', () => { expect(myFunc([])).toThrow(); }); });
👇 テストを実行
$ npx jest FAIL ./myFunc.test.ts myFunc ✕ When argument is an empty array, throw error (1 ms) ● myFunc › When argument is an empty array, throw error Empty data :( 1 | const myFunc = (data: string[]) => { 2 | if (!data.length) { > 3 | throw new Error('Empty data :('); | ^ 4 | } 5 | };
エラーが発生している箇所でテストがエラーになっている?
テストしたい関数が先に実行されてしまっているのが原因
エラーの発生は関数が返す値ではないので、expect(myFunc([]))
という書き方だと、先に関数が実行されエラーが発生してしまうので expect
でエラーをキャッチすることができずテストが落ちてしまっていた。
エラーが発生することのテストはテストする関数を別途関数でラップする必要がある
expect
に関数を渡すと実行されるので、エラーの発生する関数を別の関数で囲ってあげれば良い
// test describe('myFunc', () => { test('When argument is an empty array, throw error', () => { - expect(myFunc([])).toThrow(); + expect(() => myFunc([])).toThrow(); }); });
👇 テストを実行
$ npx jest PASS ./myFunc.test.ts myFunc ✓ When argument is an empty array, throw error (9 ms)
₍ ᐢ. ̫ .ᐢ ₎ 👌
よくみたら公式のサンプルもテスト用に関数で囲ってた。
教訓。公式のコードはちゃんと見よう。
おわり。
[参考]
- .toThrow(error?) | Expect · Jest
- javascript - How to test the type of a thrown exception in Jest - Stack Overflow
- javascript - Expect not toThrow function with arguments - Jasmine - Stack Overflow
- 【Jest入門】Errorの評価しよう~toThrow関数~ - Qiita
- Jestのexpect(matcher)を完全に理解する