Dev to webs {Coding…}

เรียนรู้การพัฒนาซอฟเวอร์ เพื่อความรู้ที่ยั่งยืน

บทที่ 21: การใช้งาน Vue Test Utils เพื่อทดสอบ Component และ State

1. Vue Test Utils คืออะไร?

Vue Test Utils เป็น Official Testing Library สำหรับ Vue.js ที่ช่วยให้คุณสามารถทดสอบ Component และฟังก์ชันต่าง ๆ ของ Vue.js ได้อย่างมีประสิทธิภาพ โดยสามารถทำงานร่วมกับ Testing Framework เช่น Jest หรือ Mocha ได้


2. การติดตั้ง Vue Test Utils

ติดตั้งผ่าน npm หรือ yarn

npm install @vue/test-utils --save-dev
npm install jest @vue/vue3-jest --save-dev

3. การตั้งค่าการทดสอบด้วย Jest

สร้างไฟล์ jest.config.js

module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/default',
  testEnvironment: 'jsdom'
};

เพิ่ม Script สำหรับรันการทดสอบใน package.json

{
  "scripts": {
    "test:unit": "jest"
  }
}

4. การสร้างและรัน Unit Test

ตัวอย่าง Component:

// Counter.vue
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};
</script>

สร้างไฟล์ทดสอบ:

// tests/unit/Counter.spec.js
import { mount } from '@vue/test-utils';
import Counter from '@/components/Counter.vue';

describe('Counter.vue', () => {
  it('renders the initial count', () => {
    const wrapper = mount(Counter);
    expect(wrapper.text()).toContain('Count: 0');
  });

  it('increments the count when button is clicked', async () => {
    const wrapper = mount(Counter);
    const button = wrapper.find('button');
    await button.trigger('click');
    expect(wrapper.text()).toContain('Count: 1');
  });
});

รันการทดสอบ:

npm run test:unit

ผลลัพธ์:

  • คุณจะเห็นสถานะการผ่านหรือไม่ผ่านของการทดสอบใน Terminal

5. การทดสอบ Props และ Events

ตัวอย่างการทดสอบ Props:

// Greeting.vue
<template>
  <h1>Hello, {{ name }}!</h1>
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true
    }
  }
};
</script>

การเขียนทดสอบ:

// tests/unit/Greeting.spec.js
import { mount } from '@vue/test-utils';
import Greeting from '@/components/Greeting.vue';

describe('Greeting.vue', () => {
  it('renders the correct name from props', () => {
    const wrapper = mount(Greeting, {
      props: { name: 'Vue.js' }
    });
    expect(wrapper.text()).toBe('Hello, Vue.js!');
  });
});

ตัวอย่างการทดสอบ Events:

// Button.vue
<template>
  <button @click="$emit('custom-event')">Click Me</button>
</template>

<script>
export default {
  name: 'Button'
};
</script>

การเขียนทดสอบ:

// tests/unit/Button.spec.js
import { mount } from '@vue/test-utils';
import Button from '@/components/Button.vue';

describe('Button.vue', () => {
  it('emits a custom event when clicked', async () => {
    const wrapper = mount(Button);
    await wrapper.trigger('click');
    expect(wrapper.emitted()).toHaveProperty('custom-event');
  });
});

6. การทดสอบ Vuex Store

ตัวอย่างการตั้งค่า Store:

// store/index.js
import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

export default store;

การเขียนทดสอบ Store:

// tests/unit/store.spec.js
import { createStore } from 'vuex';

describe('Vuex Store', () => {
  it('increments the count', () => {
    const store = createStore({
      state() {
        return { count: 0 };
      },
      mutations: {
        increment(state) {
          state.count++;
        }
      }
    });

    store.commit('increment');
    expect(store.state.count).toBe(1);
  });
});

7. การทดสอบ Integration ระหว่าง Component และ Store

การเขียนทดสอบ:

// tests/unit/CounterWithStore.spec.js
import { mount } from '@vue/test-utils';
import { createStore } from 'vuex';
import Counter from '@/components/Counter.vue';

describe('Counter.vue with Vuex', () => {
  it('increments the count using Vuex', async () => {
    const store = createStore({
      state() {
        return { count: 0 };
      },
      mutations: {
        increment(state) {
          state.count++;
        }
      }
    });

    const wrapper = mount(Counter, {
      global: {
        plugins: [store]
      }
    });

    const button = wrapper.find('button');
    await button.trigger('click');
    expect(wrapper.text()).toContain('Count: 1');
  });
});

8. สรุป

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ:

  • การตั้งค่าและใช้งาน Vue Test Utils
  • การทดสอบ Component ด้วย Props และ Events
  • การทดสอบ Vuex Store และ Integration กับ Component

ในบทถัดไป เราจะศึกษาเกี่ยวกับการ Deploy แอปพลิเคชัน Vue.js!