【Vue】单元测试(Jest/Vue Test Utils)

在这里插入图片描述

个人主页:Guiat
归属专栏:Vue

在这里插入图片描述

正文

1. Vue 单元测试简介

单元测试是确保代码质量和可维护性的重要手段,在 Vue 应用开发中,Jest 和 Vue Test Utils 是最常用的测试工具组合。

1.1 为什么需要单元测试

  • 提早发现 bug,减少线上问题
  • 重构代码时提供安全保障
  • 作为代码的活文档,帮助理解组件功能
  • 促进更好的代码设计和模块化

1.2 测试工具介绍

  • Jest: Facebook 开发的 JavaScript 测试框架,提供断言库、测试运行器和覆盖率报告
  • Vue Test Utils: Vue.js 官方的单元测试实用工具库,提供挂载组件和与之交互的方法

2. 环境搭建

2.1 安装依赖

# 使用 Vue CLI 创建项目时选择单元测试
vue create my-project

# 或在现有项目中安装
npm install --save-dev jest @vue/test-utils vue-jest babel-jest

2.2 配置 Jest

package.json 中添加 Jest 配置:

{
   
   
  "jest": {
   
   
    "moduleFileExtensions": [
      "js",
      "vue"
    ],
    "transform": {
   
   
      "^.+\\.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest"
    },
    "moduleNameMapper": {
   
   
      "^@/(.*)$": "<rootDir>/src/$1"
    },
    "testMatch": [
      "**/tests/unit/**/*.spec.[jt]s?(x)"
    ],
    "collectCoverage": true,
    "collectCoverageFrom": [
      "src/**/*.{js,vue}",
      "!src/main.js",
      "!src/router/index.js",
      "!**/node_modules/**"
    ]
  }
}

3. 编写第一个测试

3.1 组件示例

假设有一个简单的计数器组件 Counter.vue

<template>
  <div>
    <span class="count">{
  
  { count }}</span>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

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

3.2 编写测试用例

创建 tests/unit/Counter.spec.js 文件:

import {
   
    mount } from '@vue/test-utils'
import Counter from '@/components/Counter.vue'

describe('Counter.vue', () => {
   
   
  it('初始计数为0', () => {
   
   
    const wrapper = mount(Counter)
    expect(wrapper.find('.count').text()).toBe('0')
  })

  it('点击增加按钮后计数加1', async () => {
   
   
    const wrapper = mount(Counter)
    await wrapper.findAll('button').at(0).trigger('click')
    expect(wrapper.find('.count').text()).toBe('1')
  })

  it('点击减少按钮后计数减1', async () => {
   
   
    const wrapper = mount(Counter)
    await wrapper.findAll('button').at(1).trigger('click')
    expect(wrapper.find('.count').text()).toBe('-1')
  })
})

3.3 运行测试

npm run test:unit

4. Vue Test Utils 核心 API

4.1 挂载组件

// 完全挂载组件及其子组件
const wrapper = mount(Component, {
   
   
  propsData: {
   
    /* 组件 props */ },
  data() {
   
    /* 覆盖组件数据 */ },
  mocks: {
   
    /* 模拟全局对象 */ },
  stubs: {
   
    /* 替换子组件 */ }
})

// 只挂载当前组件,不渲染子组件
const wrapper = shallowMount(Component, options)

4.2 常用断言和操作

// 查找元素
wrapper.find('div') // CSS 选择器
wrapper.find('.class-name')
wrapper.find('[data-test="id"]')
wrapper.findComponent(ChildComponent)

// 检查内容和属性
expect(wrapper.text()).toContain('Hello')
expect(wrapper.html()).toContain('<div>')
expect(wrapper.attributes('id')).toBe('my-id')
expect(wrapper.classes()).toContain('active')

// 触发事件
await wrapper.find('button').trigger('click')
await wrapper.find('input').setValue('new value')

// 访问组件实例
console.log(wrapper.vm.count) // 访问数据
wrapper.vm.increment() // 调用方法

// 更新组件
await wrapper.setProps({
   
    color: 'red' })
await wrapper.setData({
   
    count: 5 })

5. 测试组件交互

5.1 测试用户输入

假设有一个表单组件 Form.vue

<template>
  <form @submit.prevent="submitForm">
    <input v-model="username" data-test="username" />
    <input type="password" v-
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

【Air】

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值