fireEventに関する考慮事項
インタラクションとイベント
ガイドラインに基づき、テストはユーザーがコード(コンポーネント、ページなど)とどのようにインタラクトするかを可能な限り反映する必要があります。これを踏まえ、fireEvent
はユーザーのアプリケーションとのインタラクションを完全に模倣するものではないものの、ほとんどのシナリオで十分な近似であることを理解しておくべきです。
fireEvent.click
を例に挙げましょう。これはクリックイベントを作成し、指定されたDOMノードにそのイベントをディスパッチします。要素がクリックされたときに何が起こるかをテストしたいだけのほとんどの場合、これは適切に機能します。しかし、ユーザーが実際に要素をクリックすると、通常は次のイベントが(順に)発生します。
- fireEvent.mouseOver(element)
- fireEvent.mouseMove(element)
- fireEvent.mouseDown(element)
- element.focus() (その要素がフォーカス可能であれば)
- fireEvent.mouseUp(element)
- fireEvent.click(element)
そして、その要素がlabel
の子要素である場合、ラベルがラベル付けしているフォームコントロールにもフォーカスが移動します。したがって、テストしようとしているのはクリックハンドラーだけであるにもかかわらず、単にfireEvent.click
を使用するだけで、ユーザーが途中で発生させている他の重要なイベントを見逃している可能性があります。
繰り返しますが、ほとんどの場合、これはテストにとって重要ではなく、単にfireEvent.click
を使用することによるトレードオフは価値があります。
代替案
コンポーネントのインタラクティブな動作に対する信頼性を高めるための、テストに対する簡単な調整をいくつか説明します。その他のインタラクションについては、user-event
を使用するか、実際の環境(例:手動、Cypressによる自動化など)でコンポーネントをテストすることを検討してください。
Keydown
keydownイベントは、現在フォーカスされている要素、body要素、またはdocument要素にディスパッチされます。これに従って、次のことを優先する必要があります。
- fireEvent.keyDown(getByText('click me'));
+ getByText('click me').focus();
+ fireEvent.keyDown(document.activeElement || document.body);
これにより、問題の要素がキーボードイベントを受け取ることができるかどうかについてもテストされます。
Focus/Blur
要素にフォーカスがあると、focusイベントがディスパッチされ、ドキュメントのアクティブな要素が変更され、以前にフォーカスされていた要素はブラーされます。この動作をシミュレートするには、fireEvent
を命令的なfocusに置き換えるだけで済みます。
- fireEvent.focus(getByText('focus me'));
+ getByText('focus me').focus();
このアプローチの良い副作用として、発火されたfocusイベントに関するアサーションは、要素がフォーカス可能でない場合に失敗します。これは、keydownイベントを続けて実行する場合に特に重要です。