0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jest と Vue Test Utils を使った Vue コンポーネントテスト実装例

Last updated at Posted at 2025-03-13

こんにちは。
この記事では、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. テストコードの解説

  1. 環境変数とグローバルオブジェクトの設定
    process.env.VUE_APP_ENVglobal.performanceの設定により、テスト実行時の環境を整えています。

  2. コンポーネントとテストツールのインポート
    import { mount } from '@vue/test-utils';を使用して、コンポーネントのマウントを行います。

  3. 初期propsの定義
    initialPropsオブジェクトで、コンポーネントの初期状態(ここでは isEnabled: false)を定義しています。

  4. コンポーネントマウントの補助関数(createWrapper)
    この関数を使うことで、複数のテストケースで同じマウントロジックを再利用し、必要に応じてpropsを上書きできます。

  5. afterEach フック
    各テストケースの後にwrapper.unmount()を実行し、テスト間の状態の干渉を防いでいます。

  6. describeとtest/itブロック
    describeで関連するテストケースをグループ化し、testまたはitブロックで個々のテストを定義しています。

  7. 非同期テスト
    async/awaitを用いて、コンポーネントのマウントやDOM更新の完了を待ってから検証を行っています。

  8. DOM要素の探索とアサーション
    wrapper.findwrapper.findAllを使って、特定のタグや要素を探し、text()attributes()を使ってその内容を検証しています。

  9. 子コンポーネントの探索
    wrapper.findComponent({ name: 'TestButton' })を用いて、TestComponent内に含まれる TestButtonコンポーネントの存在を確認しています。

  10. 深いコピー (deep copy)
    JSON.parse(JSON.stringify(initialProps))を使って、propsのディープコピーを行い、各テストケースでpropsの変更が他に影響しないようにしています。

4. まとめ

このサンプルでは、JestとVue Test Utilsを使用して、シンプルなVueコンポーネントのテストを実装する方法を示しました。

この例dは、Jestでのテスト実装の参考になれれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?