🦔

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

2021/01/31に公開

はじめに

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

解決方法その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!');
  });
});

参考

Discussion