cover image
📱

フロントエンドのテストにおける非同期処理の扱い

カテゴリ
Tech
書いた人
Keita Hino
公開日
2021/07/23
💡
概要
フロントエンドのテストを書く上で、非同期処理の扱いはハマりポイントの1つに挙げられると思います。自分もよく非同期処理が詰まっていて期待した挙動にならないということがあったので、非同期処理の扱いについて備忘録的にまとめてみようと思います。
 
非同期処理の理解を深めたい人はぜひ 🤩
 
🚀
記事はこちら!
フロントエンドのテストにおける非同期処理の扱い - Qiita
フロントエンドのテストを書く上で、非同期処理の扱いはハマりポイントの1つに挙げられると思います。自分もよく非同期処理が詰まっていて期待した挙動にならないということがあったので、非同期処理の扱いについて備忘録的にまとめてみようと思います。 もっと良い方法などあれば、コメントいただけると嬉しいです🙏 例えば以下のようなケースを考えてみましょう。 Hello World が表示されていることをテストしていますが、仮に // 画面上にHello Worldを表示するの部分が非同期処理だった場合、 Hello World が表示される前に expect(wrapper.text()).toMatch('Hello World')の検証をしてしまうかもしれません。そうなった場合、 Hello World はまだ表示されていないため、テストは失敗してしまいます。 では、どのような時に非同期処理になるのでしょうか。APIが叩かれた時に処理が非同期になるのは、比較的イメージしやすいんじゃないかなと思います。他にも処理が非同期になるケースがあるので、ここでは3つピックアップしてみます。 クリックイベントなど何らかのイベントを発火させたい時に使用する。 mount もしくは shallowMount した後に props を更新したい時に使用する。 v-model と紐づいている input 要素の値を入力したい時に使用する。 今回挙げた3パターンはどれも Promise を返すので、async/await を使うようにすれば、反映された後の状態でテストすることができます。ただし、複数の非同期処理が積まれている場合(登録ボタン押下後、登録用のAPIが叩かれるなど)は、後述する方法で明示的に非同期処理を流してあげる必要があります。 nextTick は 非同期処理を1つだけ 流すことができます。 そのため、仮に非同期処理が2つ積まれている場合は、nextTick が2つ必要になります。 flushPromises は 非同期処理を全て 流すことができます。 そのため、複数の非同期処理が積まれている場合でも、flushPromises は1つのみでOKです。 ただし、 flush-promises を別途インストールする必要があります。 自分は基本的に nextTick を使うようにしています。ただし、 初期化時の処理が全部終わってから後続処理をやりたい場合 は、mount 直後に flushPromises を使用することがあります。 flushPromises をあまり使わない理由は、非同期処理が意図せず増えてしまった場合に気付けない可能性があるからです。とはいえ、実際に flushPromises を使って困った経験はないので、この辺りはより良い方法を模索中です。 ちなみに改めて 公式ドキュメント を見てみたところ、このような記述がありました。 Use await nextTick() to ensure the DOM has updated before the test continues Functions that might update the DOM (like trigger and setValue) return nextTick, so you need await them.