🦔

Jestでclient-only内に記述したコンポーネントが読み込まれないときの対応

3 min read

はじめに

JestでNuxtのテストを書いていて、client-only or no-ssrタグで囲った部分でエラーになってしまう

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

   found in

   ---> <ClientOnlyTest>
         <Root>

環境

  • Vue.js 2.6.12
  • Nuxt.js 2.14.12
  • Jest 26.6.3
  • @vue/test-utils 1.1.2
  • vue-jest 3.0.7

Nuxtのバージョンが2.9未満の場合は<no-ssr>
それ以上の場合は<client-only>を使うようです(公式参照
この記事では、<client-only>を使用しています

解決方法その1

client-onlymount時のoptionのstubsに直接設定してあげればOK

  • client-onlyをモックするコンポーネントを作成する
~/test/mock/ClientOnlyMock.vue
<template>
  <div>
    <slot />
  </div>
</template>
  • テストでmount時に上記のモックをstubsに設定する
sample.spec.js
import { mount } from '@vue/test-utils';
import ClientOnlyTest from '~/components/ClientOnlyTest.vue';
import ClientOnlyMock from "~/test/mock/ClientOnlyMock.vue";


describe('ClientOnlyTest', () => {
  it('should show "Client Only!"', () => {
    const wrapper = mount(ClientOnlyTest, {
      stubs: {
        ClientOnly: ClientOnlyMock,
      }
    });
    const element = wrapper.find('p');
    expect(element.text()).toBe('Client Only!');
  });
});
  • メリット
    • 設定等が少なく簡易
  • デメリット
    • client-onlyがあるコンポーネントをテストするときは都度stubsにモックを設定する必要がある

解決方法その2

その1の方法だとclient-onlyがあるコンポーネントの度にモックをimportしてstubsに設定して・・・という手間があります。そこで以下のようにしてあげるといちいちテストでモックを設定しなくてもよくなります。

  • client-onlyをモックするコンポーネントを作成する(その1と同じ)
  • 任意の場所にjest.setup.jsを作成する
    • 名前は任意ですが、分かりやすいものをおすすめ
    • この記事では場所を~/test/jest.setup.jsにしています
jest.setup.js
import { config } from '@vue/test-utils';
import ClientOnlyMock from "~/test/mock/ClientOnlyMock.vue";

config.stubs['client-only'] = ClientOnlyMock;
  • jest.setup.jsjest.config.jsで読み込むように追記する
jest.config.js
module.exports = {
  setupFiles: ['./test/jest.setup.js'],
  ~省略~
  • テストコードのstubsを削除する
sample.spec.js
import { mount } from '@vue/test-utils';
import ClientOnlyTest from '~/components/ClientOnlyTest.vue';


describe('ClientOnlyTest', () => {
  it('should show "Client Only!"', () => {
    const wrapper = mount(ClientOnlyTest);
    const element = wrapper.find('p');
    expect(element.text()).toBe('Client Only!');
  });
});

jest --watchでテストを走らせている場合、一度qで中断して再度やり直さないと追加した設定ファイルやjest.config.jsの設定が反映されないようです。

参考

Discussion

ログインするとコメントできます