こんにちは。
この記事では、JestとVue Test Utilsを使用して、Vue コンポーネントの単体テストを実装する方法をシンプルな例で解説します。
1. サンプルコンポーネント (TestComponent.vue)
まず、テスト対象となるシンプルなコンポーネントの例です。
このコンポーネントは、isEnabled
というプロパティに応じて、ボタンを表示するかどうかを制御しています。
<!-- TestComponent.vue -->
<template>
<div>
<h2>テストタイトル</h2>
<p>テスト説明文1</p>
<p>テスト説明文2</p>
<!-- isEnabled が false の場合のみボタンを表示 -->
<TestButton v-if="!isEnabled" />
</div>
</template>
<script>
import TestButton from './TestButton.vue';
export default {
name: 'TestComponent',
props: {
isEnabled: {
type: Boolean,
required: true,
},
},
components: { TestButton },
};
</script>
また、シンプルなボタンコンポーネント(TestButton.vue)の例です。
<!-- TestButton.vue -->
<template>
<a :href="buttonHref" data-ga="test_button">
ボタンテキスト
</a>
</template>
<script>
export default {
name: 'TestButton',
data() {
return {
buttonHref: '/test',
};
},
};
</script>
2. Jest テストコード (TestComponent.test.js)
次に、上記コンポーネントに対するJestのテストコード例です。
この例では、コンポーネントの初期表示と、isEnabled
プロパティの値による表示制御をテストしています。
// TestComponent.test.js
// 環境変数とグローバルオブジェクトの設定
process.env.VUE_APP_ENV = 'local';
global.performance = require('perf_hooks').performance;
// コンポーネントとテストツールのインポート
import TestComponent from '@/components/test/TestComponent.vue';
import { mount } from '@vue/test-utils';
// 初期 props の定義(未有効状態:isEnabled が false)
const initialProps = {
isEnabled: false,
};
let wrapper;
/**
* createWrapper 関数
* 渡された props を用いて TestComponent をマウントする
* @param {Object} argProps - 渡す props オブジェクト。未指定の場合は initialProps を使用
*/
function createWrapper(argProps) {
const props = argProps ? argProps : initialProps;
wrapper = mount(TestComponent, {
propsData: props,
});
}
// 各テスト後にコンポーネントをアンマウントし、テスト間の影響を防ぐ
afterEach(() => {
wrapper.unmount();
});
/* =======================================================================
* テストケースのグルーピング (describe と test/it)
======================================================================== */
describe('TestComponent.vue', () => {
// 非同期テスト: コンポーネントの初期表示確認
test('初期表示', async () => {
await createWrapper();
// タイトルの確認
const title = wrapper.find('h2');
expect(title.text()).toBe('テストタイトル');
// 説明文の確認
const descriptions = wrapper.findAll('p');
expect(descriptions.at(0).text()).toBe('テスト説明文1');
expect(descriptions.at(1).text()).toBe('テスト説明文2');
// isEnabled が false の場合は TestButton が表示される
const buttonComponent = wrapper.findComponent({ name: 'TestButton' });
expect(buttonComponent.exists()).toBe(true);
// ボタンのリンク属性と data-ga の確認
const linkButton = wrapper.find('a');
expect(linkButton.attributes('href')).toBe('/test');
expect(linkButton.attributes('data-ga')).toBe('test_button');
});
// isEnabled の値による表示制御のテスト
describe('接続状態による表示確認', () => {
// isEnabled が false の場合
test('isEnabled が false の場合はボタンが表示される', async () => {
await createWrapper();
const buttonComponent = wrapper.findComponent({ name: 'TestButton' });
expect(buttonComponent.exists()).toBe(true);
});
// isEnabled が true の場合
test('isEnabled が true の場合はボタンが表示されない', async () => {
// 初期 props をディープコピーして isEnabled を true に変更
const testProps = JSON.parse(JSON.stringify(initialProps));
testProps.isEnabled = true;
await createWrapper(testProps);
const buttonComponent = wrapper.findComponent({ name: 'TestButton' });
expect(buttonComponent.exists()).toBe(false);
});
});
});
3. テストコードの解説
-
環境変数とグローバルオブジェクトの設定
process.env.VUE_APP_ENV
やglobal.performance
の設定により、テスト実行時の環境を整えています。 -
コンポーネントとテストツールのインポート
import { mount } from '@vue/test-utils';
を使用して、コンポーネントのマウントを行います。 -
初期propsの定義
initialProps
オブジェクトで、コンポーネントの初期状態(ここではisEnabled: false
)を定義しています。 -
コンポーネントマウントの補助関数(createWrapper)
この関数を使うことで、複数のテストケースで同じマウントロジックを再利用し、必要に応じてpropsを上書きできます。 -
afterEach フック
各テストケースの後にwrapper.unmount()
を実行し、テスト間の状態の干渉を防いでいます。 -
describeとtest/itブロック
describe
で関連するテストケースをグループ化し、test
またはit
ブロックで個々のテストを定義しています。 -
非同期テスト
async/await
を用いて、コンポーネントのマウントやDOM更新の完了を待ってから検証を行っています。 -
DOM要素の探索とアサーション
wrapper.find
やwrapper.findAll
を使って、特定のタグや要素を探し、text()
やattributes()
を使ってその内容を検証しています。 -
子コンポーネントの探索
wrapper.findComponent({ name: 'TestButton' })
を用いて、TestComponent内に含まれる TestButtonコンポーネントの存在を確認しています。 -
深いコピー (deep copy)
JSON.parse(JSON.stringify(initialProps))
を使って、propsのディープコピーを行い、各テストケースでpropsの変更が他に影響しないようにしています。
4. まとめ
このサンプルでは、JestとVue Test Utilsを使用して、シンプルなVueコンポーネントのテストを実装する方法を示しました。
この例dは、Jestでのテスト実装の参考になれれば幸いです。