Jestだと、テストごとに初期化したりDBにモックデータを突っ込んだりする場合にbeforeEach
に処理を書きますが、なかなかうまくいかなかったので対処した際の備忘録です。
公式Doc
beforeEach と afterEach は非同期コードをテストする と同様に非同期コードを扱えます - promise を返すか done パラメータのどちらかを選択します。 たとえば、もし initializeCityDatabase() が promiseを返すのであれば、データベースが初期化された際には promise が返されることが望まれます。
beforeEach(() => {
return initializeCityDatabase();
});
または
beforeEach(async (done) => {
await initializeCityDatabase();
done()
});
まずreturn
し忘れていないか、done()を書いているかチェック
タイムアウト時間を伸ばす
デフォルトのタイムアウト時間は5000msなので、時間がかかる処理をAsync内で行うと期待どおりに動作しない場合がある。
jest.config.js
の setupFilesAfterEnv
に指定したファイルで指定するのが良さそう。
jest.setTimeout(10000)
それでも解決しない
手元で起きた問題の場合、どうやら最初に実行されるテストだけがbeforeEach
でDBの初期化に失敗してしまうらしく、それ以降のテストは問題ない。
少々強引だが、リトライを設定すればテストは通るはず。
Jestのリトライ設定
Runs failed tests n-times until they pass or until the max number of retries is exhausted. This only works with jest-circus!
テストにおける例:
jest.retryTimes(3);
test('will fail', () => {
expect(true).toBe(false);
});
This only works with jest-circus!
と書かれているのでそのままでは使えない。
jest-circus
軽くて高機能なテストランナーらしい。
デフォルトのテストランナーはjasmine2
なので切り替える。
npm i -D jest-circus
module.exports = {
...
testRunner: 'jest-circus/runner',
...
}
リトライが使えるようになり、強引だが一応テストは通るようになった。
根本的に何故うまくいかないのか、こちらで同様の議論があった。
https://github.com/facebook/jest/issues/1256