🕳️
jestの非同期の落とし穴
非同期の落とし穴
以下のテストは 1が2でないことは明らかですが、テストはパスします。これは非同期呼び出しの落とし穴です。2行目は setTimeoutを呼び出しリターンし、テストは3行目が実行される前に終了します。it
関数内で expect
がなくてもテストは成功します。
it('should fail this test', () => {
setTimeout(() => {
expect(1).toBe(2) // should fail this line!
});
// PASS!
});
解決策 ①
解決策 ①は expect.assertions
を使います。expect.assertions(number)
は、テスト中に一定数のアサーションが実行されたことを確認します。
it('should fail this test', () => {
expect.assertions(1);
setTimeout(() => {
expect(1).toBe(2) // should fail this line!
});
// FAIL! Expected one assertion to be called but received zero assertion calls.
});
解決策 ②
jest の done コールバックをテストケースに渡し、setTimeout が終了するまで待つことで、このテストは期待通り失敗します。
it("should fail this test", (done) => {
setTimeout(() => {
expect(1).toBe(2); // FAIL!
done();
});
});
解決策 ③
解決策 ③ は 解決策 ② とやっていることは同じです。Promise オブジェクトを作成し、テストケースの中で resolve されるまで待つことで解決できます。
it("should fail this test", async () => {
await new Promise<void>((resolve) => {
setTimeout(() => {
expect(1).toBe(2); // FAIL!
resolve();
});
});
});
Discussion