テスト環境
- @vue/cli-service@4.5.15
- @vue/test-utils@1.3.0
- @vue/vue2-jest@27.0.0
- vue-jest@3.0.7
- jest@27.5.1
テスト実行とエラー処理
コンポーネントテストを実行すると
npm run test:unit
下記のようなエラーが発生しました。
<router-view>は不明なカスタム要素であるため、コンポーネントの所在が不明ですと。コンポーネントを登録してくれ!といった内容です。
console.error
[Vue warn]:
Unknown custom element: <router-view> -
did you register the component correctly? For recursive components,
make sure to provide the "name" option.
found in
---> <Anonymous>
<Root>
at warn (node_modules/vue/dist/vue.runtime.common.dev.js:621:15)
at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5962:11)
at createChildren (node_modules/vue/dist/vue.runtime.common.dev.js:6077:9)
at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5978:9)
at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6499:7)
at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3948:19)
at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4069:10)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4481:25)
at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4470:12)
at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4076:3)
at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8436:10)
at init (node_modules/vue/dist/vue.runtime.common.dev.js:3131:13)
at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:6002:9)
このエラーを解決するためには、マウントしているコンポーネントにvue-routerを使用できるようにする必要があります。
解決策は2つあります。
解決策1: stubsオプションを使用する
import { shallowMount } from '@vue/test-utils'
import App from '@/App.vue'
describe('App.vue', () => {
it('renders test', () => {
const wrapper = shallowMount(App, {
stubs: ['router-link', 'router-view']
})
expect(wrapper.isVueInstance).toBeTruthy()
})
})
shallowMount()を使用すると、子コンポーネントをstubとして表示してくれるので子コンポーネントをレンダリングする必要がないとき(今回のようなApp.vueの描画テストのみの場合など)は、上記の方法でテストを書きます。
stubsオプションとして<router-view>や<router-link>を登録しておくことで、vue-routerのエラーが発生しなくなります。
解決策2: localVue による Vue Router のインストール
Vue.jsアプリケーションでは、vuexやvue-routerなどのグローバルプラグインを使用して開発を行うと思います。Vue Test Utilsでは、vuexやvue-routerなどのグローバルプラグイン、ミックスイン、コンポーネントをテストのエントリに設定することができます。
そのためには、createLocalVue
()を使用します。
import { shallowMount, createLocalVue } from '@vue/test-utils'
import VueRouter from 'vue-router'
const localVue = createLocalVue()
localVue.use(VueRouter)
describe('App.vue', () => {
it('renders test', () => {
const wrapper = shallowMount(App, {
localVue
})
expect(wrapper.isVueInstance).toBeTruthy()
})
})
上記のように書くことでテスト内にvue-routerプラグインを使うことができ、<router-view>コンポーネントも認識されるようになります。
個人的な意見ですが、コンポーネントテストにおいて、vue-routerに依存する<router-view>の中身を検証する必要はないと考えています。
基本的にルーティングはアプリ全体の構造に関連しているので、結合テストやe2eテストで検証するのが一般的です。
なのでvue-routerに依存する<router-view>や<router-link>などのコンポーネントについては、stubsオプションやlocalVueを使ってモックするのが奨励されています。
コメント