9.1 変換前のテストファイルの読み方
■ 要点まとめ
- 変換前は**クラスコンポーネント(vue-property-decorator)**ベースのテスト
- テスト対象はVuexモジュール連携+v-model付きの親子コンポーネント
- shallowMount+createLocalVueでローカルVueインスタンスを作成している
- Vuexストアを手動モックしている
- テスト内容は主に2つ
- ① スナップショットテスト(レンダリング検証)
- ② ボタンクリック時にアクションが呼ばれるかの検証
■ ✅ 変換前テストコードの全体像
// ファイル名: src/tests/components/ParentComponent.spec.ts
// 必要な関数をvue-test-utilsからインポート(コンポーネントをテスト用にマウントするため)
import { shallowMount, createLocalVue } from '@vue/test-utils';
// Vuexストアをインポート(ローカルインスタンスに組み込むため)
import Vuex from 'vuex';
// テスト対象の親コンポーネントをインポート
import ParentComponent from '@/components/ParentComponent.vue';
// テスト用にスタブ化する子コンポーネントをインポート
import ChildComponent from '@/components/ChildComponent.vue';
// ローカルなVueインスタンスを作成(グローバル汚染を防ぐため)
const localVue = createLocalVue();
// ローカルVueインスタンスにVuexを組み込む
localVue.use(Vuex);
// ParentComponentのテストスイート開始
describe('ParentComponent.vue', () => {
// テストごとに初期化されるVuexストア
let store: any;
// 各テスト実行前に毎回ストアを作り直す
beforeEach(() => {
// モックされたVuexストアを作成
store = new Vuex.Store({
modules: {
sampleModule: {
namespaced: true, // モジュールを名前空間付きで定義
state: { text: 'テスト用テキスト', currentRoute: { name: 'home', path: '/' } }, // 初期state
getters: {
textLength: (state: any) => state.text.length, // テキストの長さを返すgetter
currentRouteName: (state: any) => state.currentRoute.name, // 現在ルート名を返すgetter
},
actions: {
updateText: jest.fn(), // updateTextアクションをjestモック関数にする
},
},
},
});
});
// スナップショットテスト:レンダリング結果が意図通りかを検証
it('スナップショットと一致すること', () => {
// ParentComponentをshallowMount(子コンポーネントはスタブ化)
const wrapper = shallowMount(ParentComponent, {
localVue,
store,
stubs: { ChildComponent },
});
// コンポーネントのDOMツリーが以前のスナップショットと一致するか確認
expect(wrapper.element).toMatchSnapshot();
});
// ボタンクリックでアクションが呼び出されるかをテスト
it('ボタンをクリックするとupdateTextが呼ばれること', async () => {
// ParentComponentをshallowMount(子コンポーネントはスタブ化)
const wrapper = shallowMount(ParentComponent, {
localVue,
store,
stubs: { ChildComponent },
});
// 子コンポーネントとバインドしているchildValueを直接書き換える
(wrapper.vm as any).childValue = '新しいテキスト';
// ボタン要素を取得
const button = wrapper.find('button');
// ボタンクリックイベントを発火
await button.trigger('click');
// モジュールのdispatchが正しく呼ばれたか検証(引数に新しいテキストが渡されたか)
expect(store._modulesNamespaceMap['sampleModule/'].context.dispatch).toHaveBeenCalledWith('updateText', '新しいテキスト');
});
});
■ ✅ ここでやっていることを簡単に言うと…
- ローカルVueインスタンスを作る(本番環境を汚さないため)
- Vuexストアをモックする(本物のサーバーやDBに依存しないため)
- shallowMountでコンポーネントだけ検証する(子コンポーネントの中身は無視)