🫥

React/Jestでのテストで「要素が存在しない」を確認する

2023/02/13に公開

これはスペースマーケット Engineer Blog の記事です。
書き手はfumink7です。

不揃いバームクーヘンを食べながら書いています。
おいしいね 🙌


なんの記事?

React/Jest(Testing-library)で「要素が存在しない」を確認する方法についてです。
ほぼここ↓に載っている内容なのでこちら見れば済む話なのですが、ちょっと整理しておこうかと。

https://testing-library.com/docs/guide-disappearance/

あったものが存在しなくなったことを確認したい

たとえば非同期処理が実行された結果、要素が削除されたことを確認するようなテストですね。

waitForで要素が存在しなくなるまで待つ

以下のようにwaitForを使うことで要素がなくなったことを確認できます。
正確に言うと、expectをwaitForのタイムアウトまで実行し続けて期待値が返ってきたら(エラーが発生しなくなったら)テスト成功になりますね。

await waitFor(() => {
  expect(screen.queryByAltText('テストだよ')).not.toBeInTheDocument()
})

余談ですが.not.toBeInTheDocument()toHaveLength(0)みたいに書いても問題ないですがテストの意味がわかりやすいよね、とのこと。

waitForElementToBeRemovedで要素がなくなったことをキャッチ

waitForElementToBeRemovedを使って要素がなくなったことをキャッチアップする方法もあります。
MutationObserverを利用しているので、DOMに変更があった場合にのみチェックが走るため効率的とのこと。

await waitForElementToBeRemoved(() => queryByText('テストだよ'))

最初存在しない → 処理の結果、やっぱり存在しないことを確認したい

レンダリング→非同期でのAPIへのデータ取得→View反映というコンポーネント表示の確認のテストで

  1. 取得したデータがある場合、List表示されること
  2. 取得したデータがなかった場合、List表示されないこと

という確認を行いたかった場合、2はどうすべきなんだ?と迷いました。
というのも、waitForで要素がなかったことを確認しようとしてもそれがデータ取得処理の前なのか後なのか確認できないということです。

render(<TargetComponent />)

// render直後はListが表示されておらず、非同期でのデータ取得をおこないデータが存在すれば表示、無ければListは表示されないまま

// ↓リストがないことを確認できた時(成功時)、それがデータ取得処理後に行われたという保証がない
await waitFor(() => {
  expect(screen.queryByAltText('テストだよ')).not.toBeInTheDocument()
})

非同期処理が完了する(であろう)時間を確保する

シンプルなやり方ですが、データ取得処理が終わるまで待ってからfindByが失敗することを期待するテストです。
↓この例だとあくまで「100ms待てば終わっているだろう」というものでデータ取得処理が確実に終わったことを保証するものではないので、時間設定が難しいかも?

await expect(
  screen.findByRole('list', {}, { timeout: 100 }),
).rejects.toThrow()

非同期処理の完了を検知する方法はあるのか??

もちろんコードにもよると思うのですが、コンポーネント内のこの非同期処理完了を検知したらアサーションを実行、みたいなことが書けるのでしょうか?
SpyOnとか利用すればできそうな気がするのですが、結局よくわからず…

続報を待て🕵🏾

参考:実行環境

テスティングフレームワークはJest、UIテストのためにTesting Libraryを使用しています

  • typescript@4.9.4
  • React@18.2.0
  • jest@28.1.0
  • @testing-library/react@13.3.0

(いつもの宣伝)スペースマーケットはエンジニアを募集しています!

もちろんエンジニア大募集中です!

https://www.wantedly.com/projects/1113570
https://www.wantedly.com/projects/1113544
https://www.wantedly.com/projects/1061116

スペースマーケット Engineer Blog

Discussion