#Nuxt.js で Jest を利用したテストを実装する際にエンカウントしたワーニングやエラーの対処法メモ

Nuxt.js で Jest を利用したテストを実装する際にエンカウントしたワーニングやエラーの対処法メモ

なんかタイトル日本語でOK状態だけど、つまりそういうこと。

Jest でテストを書いていたのだけど、いろいろぶち当たったので都度メモしていく。

[Vue warn]: Unknown custom element: <nuxt-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Nuxt で作られたプロジェクトにおいて Jest を利用してテストをする際、下記の様な [Vue warn] が出てしまう。

    console.error node_modules/vue/dist/vue.runtime.common.dev.js:621
      [Vue warn]: Unknown custom element: <nuxt-link> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

      found in

      ---> <Anonymous>
             <Root>

原因はいまいちわからないのだけど、 <nuxt-link><a>レンダリングしてくれないから的なサムシング。

そこで、 RouterLinkStub を使えば解決できそうな感じが公式にあった。

vue-test-utils.vuejs.org

つまり、

import { mount } from '@vue/test-utils'
import TheHeader from '@/components/sections/TheHeader.vue'

describe('components/sections/TheHeader.vue', () => {

  describe('template', () => {
    test('template test', () => {
      const wrapper = mount(TheHeader)
      expect(wrapper.contains('header')).toBe(true)
    })
  })
})

といったテストがあったとして、

import { mount, RouterLinkStub } from '@vue/test-utils'
import TheHeader from '@/components/sections/TheHeader.vue'

describe('components/sections/TheHeader.vue', () => {

  describe('template', () => {
    test('template test', () => {
      const wrapper = mount(TheHeader, { stubs: { NuxtLink: RouterLinkStub }})
      expect(wrapper.contains('header')).toBe(true)
    })
  })
})

のように修正すればOK。

<nuxt-link> のスタブを用意して上げる感じか。

こちらが大変参考になった。ありがとうございました。

onigra.github.io

[Vue warn]: Unknown custom element: <no-ssr> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

しかし、今度は <no-ssr> についてもスタブが必要となってくる。

まったくイメージわかないのでいろいろ調べていたら、こちらに行き当たった。

github.com

どうやら jest の setup に下記の様なスクリプトを書いてあげれば良さそう。

spec/util/jest.setup.js

import VueTestUtils from '@vue/test-utils';

Vue.config.silent = true;

// Mock Nuxt components
VueTestUtils.config.stubs['no-ssr'] = '<span><slot /></span>';

package.json には setupFiles を追加

・・・
  "jest": {
    "setupFiles": [
      "<rootDir>/spec/unit/jest.setup.js"
    ],
・・・
  },
・・・

これで <no-ssr>[Vue warn] も出なくなった。

すべて jest.setup.js にまとめる

RouterLinkStub を使わなくても jest.setup.js<nuxt-link> のスタブを追加すればよいのではないか?

つまり、

import VueTestUtils from '@vue/test-utils';

// Mock Nuxt components
VueTestUtils.config.stubs['nuxt-link'] = '<a><slot /></a>';
VueTestUtils.config.stubs['no-ssr'] = '<span><slot /></span>';

このように任意のスタブを追加していく。

せっかくなので、 <nuxt-link>RouterLinkStub を使おう。

一応これでWARNは出なくなったけど、 <nuxt-link>RouterLinkStub を使いたい。

github.com

なので、最終的に spec/util/jest.setup.js はこのようになった。

import VueTestUtils from '@vue/test-utils';

// Mock Nuxt components
VueTestUtils.config.stubs['nuxt-link'] = VueTestUtils.RouterLinkStub;
VueTestUtils.config.stubs['no-ssr'] = '<span><slot /></span>';

他にも VueTestUtilsでてこないのかな。なんか思いついたらプルリク送りたい気もする。

router を利用する場合?

Page Component ではなく、部品として作成した Component のテストにて、routerが見つけられずこんなエラーが出た場合は、

TypeError: Cannot read property 'fullPath' of undefined

下記の通りに修正すればOK。

vue-test-utils.vuejs.org

props はどうするの?

mount のところに仕込んであげれば良い。

import { mount } from '@vue/test-utils'
import TheHeader from '@/components/sections/TheHeader.vue'

describe('components/sections/TheHeader.vue', () => {

  describe('template', () => {
    test('template test', () => {
      const wrapper = mount(TheHeader, { props: hogehoge: { name: "hogehoge" } })
      expect(wrapper.contains('header')).toBe(true)
    })
  })
})

んー、きりがないので一旦このくらいにしておこうかなw