4
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

はじめに

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

4
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
4
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?