9.3 Vuex周りのモック方法の変更


■ 要点まとめ


■ ✅ Composition API版でVuexモックの主な変更点

項目 クラスコンポーネント時代 Composition API移行後
モック対象 modules, state, getters, actions を定義してVuex.Storeを作る 同じくmodules, state, getters, actionsをVuex.Storeで作成
useStoreの有無 使わない(vuex-classでデコレート) 使わない(setup関数内で手動importか、別フックから取得)
storeの参照方法 @State @Getter で自動バインド setup関数でcomputed等に手動バインド
テストからの操作方法 (wrapper.vm as any).〇〇でアクセス wrapper.vm.〇〇でアクセス可能

✅ 結論として、

モックの作り方自体は「今まで通り」でOKですが、

テスト対象側の読み方・触り方だけがシンプルに変わる、というイメージです。


■ ✅ 変更後のモックストア作成例

// ファイル名: storeMock.ts
import Vuex from 'vuex';

// Vuexモックストア作成関数
export function createStoreMock() {
  return new Vuex.Store({
    modules: {
      sampleModule: {
        namespaced: true,
        state: {
          text: 'テスト用テキスト',
          currentRoute: { name: 'home', path: '/' },
        },
        getters: {
          textLength: (state: any) => state.text.length,
          currentRouteName: (state: any) => state.currentRoute.name,
        },
        actions: {
          updateText: jest.fn(), // Actionのモック
        },
      },
    },
  });
}


■ ✅ テストファイルでの使い方(Composition API版)

// ファイル名: ParentComponent.spec.ts
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import ParentComponent from '@/components/ParentComponent.vue';
import ChildComponent from '@/components/ChildComponent.vue';
import { createStoreMock } from '@/tests/storeMock';

const localVue = createLocalVue();
localVue.use(Vuex);

describe('ParentComponent.vue (Composition API版)', () => {
  let store: any;

  beforeEach(() => {
    store = createStoreMock();
  });

  it('スナップショットと一致すること', () => {
    const wrapper = shallowMount(ParentComponent, {
      localVue,
      store,
      stubs: {
        ChildComponent,
      },
    });
    expect(wrapper.element).toMatchSnapshot();
  });

  it('ボタンをクリックするとupdateTextが呼ばれること', async () => {
    const wrapper = shallowMount(ParentComponent, {
      localVue,
      store,
      stubs: {
        ChildComponent,
      },
    });

    // childValueを直接変更
    wrapper.vm.childValue = '新しいテキスト';

    // ボタンクリック
    const button = wrapper.find('button');
    await button.trigger('click');

    // Vuexアクションが呼ばれたか検証
    expect(store._modulesNamespaceMap['sampleModule/'].context.dispatch).toHaveBeenCalledWith('updateText', '新しいテキスト');
  });
});