こんにちは。野中やすおです。
mountとは何か?
Vue Test Utilsのmountは、Vueコンポーネントをフルレンダリングするためのメソッドです。mountメソッドを使うことでテスト中に Vueコンポーネントを実際に DOM にマウントし、そのコンポーネントのライフサイクルフックや子コンポーネントも完全に実行・レンダリングされます。 mountの使用する時には、親コンポーネントが持っている子コンポーネントもフルレンダリングされます。
mountの特徴
フルレンダリング
mountでは、コンポーネントのライフサイクルフックや子コンポーネントも完全に実行・レンダリングされます。
shallowMountとは何か?
次にshallowMountの紹介です。shallowMountは、文字通りVue コンポーネントを「浅くマウント」します。
どういうことかというと、親コンポーネントをマウントする際にテスト対象となるコンポーネント内に含まれる子コンポーネントをスタブ(stub)で置き換えています。スタブへ置き換えることによって、テストを親コンポーネントだけに絞り、子コンポーネントの内部実装や振る舞いに影響されずに親コンポーネントのテストを実施することができます。
スタブ(stub)とは何か?
Vue Test Utilsにおけるスタブとは、テスト対象となるコンポーネントをダミーのコンポーネントに置き換えて、テストの対象を特定のコンポーネントや動作に絞り込むために使用されます。
shallowMountの特徴
shallowMount
の特徴として、次の特徴が挙げられます。
子コンポーネントのスタブ化
親コンポーネントをマウントする際にその内部で使用されている子コンポーネントはスタブ化されます。よって子コンポーネントの実際の振る舞いや状態がテストに影響を及ぼさないようになります
テストの単純化
shallowMountを使うと親コンポーネントのテストに集中することができるため、テストの複雑さが減少します。
性能向上
もちろんshallowMountを使うと実際の子コンポーネントをレンダリングすることなくテストを実行することができるため、単にmountを使うようりテストの速度が向上します。
mountとshallowMountの具体例
それでは、mountとshallowMountの具体例をコードを見ながら見ていきます。
まずは、HelloMountChildComponent.vueという子コンポーネントを作成します。Hello from Child!という文言をspanタグでくくったとても単純なコードです。
1 2 3 4 |
<script setup lang="ts"></script> <template> <span>Hello from Child!</span> </template> |
次にHelloMountParentComponent.vueという親コンポーネントを作成し、先ほど作成したHelloMountChildComponentをインポートします。
1 2 3 4 5 6 7 8 9 |
<script setup lang="ts"> import HelloMountChildComponent from "./HelloMountChildComponent.vue"; </script> <template> <div> <HelloMountChildComponent /> </div> </template> |
そこでこれらのファイルのテストファイルHelloMountParentComponent.spec.tsを用意します。
1 2 3 4 5 6 7 8 9 |
import { mount, shallowMount } from "@vue/test-utils"; import HelloMountParentComponent from "./HelloMountParentComponent.vue"; describe("HelloMountParentComponent with mount", () => { test("renders child component", () => { const wrapper = mount(HelloMountParentComponent); expect(wrapper.find("span").text()).toBe("Hello from Child!"); }); }); |
このテストファイルはspanタグ内でHello from Child!がレンダリングされているか確認するものです。
yarn vitest HelloMountParentComponent.spec.tsでテストを実行すると….
問題なくテストが完了します!
次にshallowMountをインポートし、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { mount, shallowMount } from "@vue/test-utils"; import HelloMountParentComponent from "./HelloMountParentComponent.vue"; describe("HelloMountParentComponent with mount", () => { test("renders child component", () => { const wrapper = mount(HelloMountParentComponent); expect(wrapper.find("span").text()).toBe("Hello from Child!"); }); }); describe("HelloMountParentComponent with shallowMount", () => { test("renders child component", () => { const wrapper = shallowMount(HelloMountParentComponent); expect(wrapper.find("span").text()).toBe("Hello from Child!"); }); }); |
テストを実行しようとすると….
こちらではエラーになってしまいます。つまり改めて上記の例でもわかる通り、mountとshallowMountの違いは子コンポーネントをテスト対象とするかどうかです。
先ほどのテストの代わりにHelloMountChildComponentがスタブになっているかどうかを確認するテストを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 |
import { mount, shallowMount } from "@vue/test-utils"; import HelloMountParentComponent from "./HelloMountParentComponent.vue"; describe("HelloMountParentComponent with shallowMount", () => { test("child component is stubbed", () => { const wrapper = shallowMount(HelloMountParentComponent); expect( wrapper.findComponent({ name: "HelloMountChildComponent" }).exists() ).toBe(true); }); }); |
こちらのテストはエラーにならず問題なく実行されます。
またmountメソッドもstubsオプションを使用することで子コンポーネントをスタブ化することができます。以下がその例です。
1 2 3 4 5 6 7 8 |
describe("HelloMountParentComponent with stubs", () => { test("stubs HelloMountChildComponent", () => { const wrapper = mount(HelloMountParentComponent, { stubs: ["HelloMountChildComponent"], }); // HelloMountChildComponent がスタブ化されているため、その内部の内容はレンダリングされない }); }); |
参考
The official testing suite utils for Vue.js 3…
マウンティングオプションに関するドキュメントがVue Test Utils V2内で探しても見つからなかったので、V1のURLをはっておきます。
Vue コンポーネントをテストするためのユーティリティ…