3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

awaitとwaitForの違い TypeError: Cannot read properties of null (reading 'length')エラー対応 (Jest × Testing Library)

Last updated at Posted at 2024-11-10

はじめに

かなり苦労しました。

問題

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

awaitは、async関数内でPromiseの結果(resolve、reject)が返されるまで待機する演算子。(処理を一時停止する)

Copilotによると、await expect(recordCount + 1).toBe(newRecordCount);は、expectの結果が返るまで待機するという意味にはならない。
expectは同期的に動作するため、awaitを付けても非同期処理として待機することはできない。

そのため、await expect(recordCount + 1).toBe(newRecords.length);の部分は、awaitを付けても newRecordsの結果を待つわけではない。
console.logで確認したところ、undefinedが返ってきていた。
awaitの場合、undefinedが返ってきたら再計算することはない。

waitFor

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

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?