はじめに
awaitとawait waitForの違いを理解できておらず、なかなか解決できませんでした。
問題
TypeError: Cannot read properties of null (reading 'length')のエラーが発生する。
// エラーメッセージ
TypeError: Cannot read properties of null (reading 'length')
49 | // console.log("newRecordCount", newRecordCount);
50 |
> 51 | await expect(recordCount + 1).toBe(newRecords.length);
| ^
52 | });
53 |
at length (src/tests/componenteSample.spec.jsx:51:50)
at call (src/tests/componenteSample.spec.jsx:2:1)
at Generator.tryCatch (src/tests/componenteSample.spec.jsx:2:1)
at Generator._invoke [as next] (src/tests/componenteSample.spec.jsx:2:1)
at asyncGeneratorStep (src/tests/componenteSample.spec.jsx:2:1)
at asyncGeneratorStep (src/tests/componenteSample.spec.jsx:2:1)
解決方法
// エラーのコード
const newRecords = await waitFor(() => {
const elements = screen.getAllByTestId('record');
if (elements.length > recordCount) {
return elements;
}
return null;
});
const newRecordCount = newRecords.length;
await expect(recordCount + 1).toBe(newRecords.length);
await
copilotの解説は以下。
await は、Promise が解決される(resolve または reject される)まで待機する演算子
非同期関数内で使用され、処理を一時停止する
「await expect(recordCount + 1).toBe(newRecordCount);」は、
awaitを付けてもexpectの結果が返るまで待機するという意味にはならない。
- console.logで確認すると、undefinedが返ってきていた
- awaitの場合、undefinedが返ってきたら再計算しない
await waitFor
copilotの解説は以下。
waitFor は、特定の条件が満たされるまで繰り返し実行される関数
React Testing Library で使用され、非同期にレンダリングされる要素や状態の変化を待つために使用する
デフォルトの間隔は50msで、デフォルトのタイムアウトは1000ms(copilot)
- expectを同期的に待機するためには、waitFor関数の中でexpectを使用すればよい
- waitFor内でexpectを使用することで、条件が満たされるまで待機できる
Testing Libraryのドキュメントによると、waitForはタイムアウトに達するまで何度でもコールバックを実行する。デフォルトの間隔は50msで、デフォルトのタイムアウトは1000ms。
// 成功したコード
await waitFor(() => {
const newRecords = screen.getAllByTestId('record');
const newRecordCount = newRecords.length;
console.log("newRecordCount", newRecordCount);
expect(recordCount + 1).toBe(newRecordCount);
});
参考
async function内でPromiseの結果(resolve、reject)が返されるまで待機する(処理を一時停止する)演算子のこと。
https://qiita.com/soarflat/items/1a9613e023200bbebcb3#await%E3%81%A8%E3%81%AF
testing-libraryのドキュメント
https://testing-library.com/docs/dom-testing-library/api-async/#waitfor