@nuxt/test-utilsのmountSuspendedについて
はじめに
- @vue/test-utils(Vitest)のMount関数のラッパー関数
- マウントするコンポーネントを非同期でPromise.resolveしてくれるので、マウントを待つ処理がいらない
- 個々のマウントの把握・チェックをしたいなら大人しくMountとPromise.resolveと$nextTickつかっときましょう
Nuxtの一次情報にはなんと書かれているのか
Helpers項目の1個目に載ってます。
@nuxt/test-utils特有のヘルパー関数らしく、説明は以下
mountSuspended
Nuxt 環境内に任意の Vue コンポーネントをマウントできるため、Nuxt プラグインからの非同期セットアップとインジェクションへのアクセスが可能になります。
なるほどわからん。(名推理)
その直後に
Under the hood, mountSuspended wraps mount from @vue/test-utils, so you can check out the Vue Test Utils documentation for more on the options you can pass, and how to use this utility.
とのことで、Vitestのmountのラッパーだよーということが書いてあります。
当たり前ですが、Vitestのmount関数の理解が先ということですな。
mount関数の記事は星の数ほどはないですが、そこそこあるので割愛します。
mountSuspendedの内部動作
ポイントは非同期処理の取り扱いにあります。通常のmount
関数と異なり、mountSuspended
は内部で以下のような処理を行っています:
- コンポーネントをマウント
- 非同期処理の解決を自動的に待機
- Nuxt特有のインジェクションやプラグインのセットアップを完了させる
これにより、テストコード内でawait nextTick()
やflushPromises()
のような追加の待機処理を書かなくても良くなるという利点があるわけですよ!
使用例と従来の方法との比較
mountSuspendedを使った場合
import { mountSuspended } from '@nuxt/test-utils'
import MyComponent from '~/components/MyComponent.vue'
describe('MyComponent', () => {
it('properly loads async data', async () => {
const wrapper = await mountSuspended(MyComponent)
// この時点で非同期処理は完了している
expect(wrapper.text()).toContain('データが読み込まれました')
})
})
従来のmountを使った場合
import { mount } from '@vue/test-utils'
import MyComponent from '~/components/MyComponent.vue'
describe('MyComponent', () => {
it('properly loads async data', async () => {
const wrapper = mount(MyComponent)
// 非同期処理の完了を待つ必要がある
await flushPromises()
await wrapper.vm.$nextTick()
expect(wrapper.text()).toContain('データが読み込まれました')
})
})
mountSuspendedのメリットとデメリット
メリット
- テストコードがシンプルになる
- 非同期処理の待機漏れによるフレーキーテストを防げる
- Nuxt特有の機能(プラグインやインジェクション)が正しく初期化される
デメリット
- 非同期処理の各ステップを細かく制御したい場合には不向き
- デバッグが難しくなる可能性がある(どのタイミングで何が起きているか把握しづらい)
- マウント処理の詳細な把握が必要な場合は従来の方法が適している
どんなときに使うべきか
以下のような場合にmountSuspended
の使用をおすすめします:
- Nuxtのコンポーネントをシンプルにテストしたい
-
useAsyncData
やuseFetch
などの非同期データ取得を含むコンポーネントのテスト - Nuxtプラグインやプロバイダーに依存するコンポーネントのテスト
一方で、以下の場合は従来のmount
と明示的な非同期処理の方が適しています:
- 非同期処理の各ステップを個別にテストしたい
- ローディング状態など、特定の中間状態を検証したい
- 複雑なユーザーインタラクションを含むテストシナリオ
まとめ
mountSuspended
は、Nuxtアプリケーションのテストを書く際に非常に便利なヘルパー関数です。特に非同期処理を含むコンポーネントのテストを簡略化できる点が大きな利点です。
ぶっちゃけ個人的な使用感ですが、現段階ではmount
で毎回await nextTick()
とかで処理進めた方がいいと思います。
非同期処理の解決を自分で行いながらテストして行った方が、統合テストを流れに沿って実装できるかなと思います。