[{"data":1,"prerenderedAt":357},["ShallowReactive",2],{"content:\u002Fposts\u002F2025\u002Ftesting-vue-components-with-vitest":3,"surround:\u002Fposts\u002F2025\u002Ftesting-vue-components-with-vitest":346},{"id":4,"title":5,"body":6,"canonical":16,"categories":324,"date":326,"description":31,"draft":327,"extension":328,"image":329,"meta":330,"navigation":331,"path":332,"permalink":333,"readingTime":334,"recommend":339,"references":333,"seo":340,"sitemap":341,"stem":342,"tags":343,"type":333,"updated":326,"__hash__":345},"content\u002Fposts\u002F2025\u002Ftesting vue components with vitest.md","【翻译】使用 Vitest 测试 Vue 组件",{"type":7,"value":8,"toc":311},"minimark",[9,20,23,26,29,32,37,45,61,65,68,79,86,94,101,107,114,122,133,139,142,150,153,159,190,194,200,213,219,222,228,231,238,259,263,268,271,277,280,286,290,299,302,305,308],[10,11,12,13],"p",{},"原文地址：",[14,15,19],"a",{"href":16,"rel":17},"https:\u002F\u002Fdev.to\u002Fjacobandrewsky\u002Ftesting-vue-components-with-vitest-5c21",[18],"nofollow","Testing Vue components with Vitest",[21,22],"hr",{},[10,24,25],{},"现代前端开发需要强大的测试实践，以确保应用程序的可靠性和可维护性。",[10,27,28],{},"值得庆幸的是，在 Vue 中我们可以使用一个由 Vite 提供支持的神奇工具 - Vitest，它可以让我们轻松测试 Vue 组件。",[10,30,31],{},"在本文中，我将深入探讨如何使用 Vitest 来测试 Vue 组件。",[33,34,36],"h2",{"id":35},"什么是vitest","什么是Vitest",[10,38,39,44],{},[14,40,43],{"href":41,"rel":42},"https:\u002F\u002Fcn.vitest.dev\u002F",[18],"Vitest","是一个速度极快的测试框架，旨在与现代构建工具 Vite 无缝协作。这就是为什么 Vitest 是测试 Vue 组件的绝佳选择：",[46,47,48,52,55,58],"ol",{},[49,50,51],"li",{},"速度：Vitest 基于 Vite构建，利用其快速的构建时间和热更新（HMR）；",[49,53,54],{},"TypeScript 支持：Vitest 具有开箱即用的TypeScript支持；",[49,56,57],{},"Vue集成：它与Vue Test Utils （Vue的官方测试库）配合良好；",[49,59,60],{},"丰富的功能：Vitest包括快照测试、模拟和监视模式等功能，可简化开发。",[33,62,64],{"id":63},"使用vitest测试vue组件","使用Vitest测试Vue组件",[10,66,67],{},"首先，确保您有一个使用Vite设置的Vue项目。然后，安装Vitest及相关库",[69,70,76],"pre",{"className":71,"code":73,"language":74,"meta":75},[72],"language-shell","pnpm install --save-dev vitest @vue\u002Ftest-utils vue\n","shell","",[77,78,73],"code",{"__ignoreMap":75},[10,80,81,82,85],{},"添加 ",[77,83,84],{"code":84},"vitest.config.ts"," 文件来配置 Vitest",[69,87,92],{"className":88,"code":90,"filename":84,"language":91,"meta":75},[89],"language-ts","import vue from '@vitejs\u002Fplugin-vue'\nimport { defineConfig } from 'vitest\u002Fconfig'\n\nexport default defineConfig({\n    plugins: [vue()], \u002F\u002F 测试vue项目需要引入vue驱动\n    test: {\n        globals: true,\n        environment: 'jsdom', \u002F\u002F 使用浏览器模式测试\n        \u002F\u002F setupFiles: '.\u002Fvitest.setup.ts', \u002F\u002F 需要全局变量时启用\n    }\n})\n","ts",[77,93,90],{"__ignoreMap":75},[10,95,96,97,100],{},"如果需要执行全局配置（如模拟全局变量），请创建 ",[77,98,99],{"code":99},"vitest.setup.ts"," 文件",[69,102,105],{"className":103,"code":104,"filename":99,"language":91,"meta":75},[89],"import matchers from '@testing-library\u002Fjest-dom\u002Fmatchers';\nimport { expect } from 'vitest';\n\nexpect.extend(matchers);\n",[77,106,104],{"__ignoreMap":75},[10,108,109,110,113],{},"让我们为Vue组件编写一个简单的测试。创建 ",[77,111,112],{"code":112},"HelloWorld.vue"," 组件",[69,115,120],{"className":116,"code":118,"filename":112,"language":119,"meta":75},[117],"language-vue","\u003Cscript setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst message = ref('Hello, Vue!')\n\nfunction updateMessage() {\n    message.value = 'You clicked the button!'\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n    \u003Cdiv>\n        \u003Ch1>{{ message }}\u003C\u002Fh1>\n        \u003Cbutton @click=\"updateMessage\">\n            Click Me\n        \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","vue",[77,121,118],{"__ignoreMap":75},[10,123,124,125,128,129,132],{},"在 ",[77,126,127],{"code":127},"tests"," 目录中创建 ",[77,130,131],{"code":131},"HelloWorld.spec.ts"," 文件：",[69,134,137],{"className":135,"code":136,"filename":131,"language":91,"meta":75},[89],"import { mount } from '@vue\u002Ftest-utils';\nimport { describe, expect, it } from 'vitest';\n\nimport HelloWorld from '..\u002Fsrc\u002Fcomponents\u002FHelloWorld.vue';\n\ndescribe('HelloWorld.vue', () => {\n    it('renders the correct message', () => {\n        const wrapper = mount(HelloWorld);\n        expect(wrapper.text()).toContain('Hello, Vue!');\n    });\n\n    it('updates the message when the button is clicked', async () => {\n        const wrapper = mount(HelloWorld);\n        await wrapper.find('button').trigger('click');\n        expect(wrapper.text()).toContain('You clicked the button!');\n    });\n});\n",[77,138,136],{"__ignoreMap":75},[10,140,141],{},"使用以下命令运行测试：",[69,143,148],{"className":144,"code":146,"language":147,"meta":75},[145],"language-bash","npx vitest\n","bash",[77,149,146],{"__ignoreMap":75},[10,151,152],{},"为了获得更具互动性的体验，您可以使用watch来监听文件改动：",[69,154,157],{"className":155,"code":156,"language":147,"meta":75},[145],"npx vitest --watch\n",[77,158,156],{"__ignoreMap":75},[160,161,162,168,171,182],"alert",{},[163,164,165],"template",{"v-slot:title":75},[10,166,167],{},"译者注",[10,169,170],{},"vitest 会自动监听文件变化，原文中的此处内容可忽略",[10,172,173,174,177,178,181],{},"你也可以在 ",[77,175,176],{"code":176},"package.json"," 中添加一行命令，使用 ",[77,179,180],{"code":180},"pnpm run test","来运行测试",[69,183,188],{"className":184,"code":186,"filename":176,"language":187,"meta":75},[185],"language-json","{\n  \"scripts\": {\n    \"test\": \"vitest\",\n  },\n}\n","json",[77,189,186],{"__ignoreMap":75},[33,191,193],{"id":192},"奖励额外的测试技术","奖励：额外的测试技术",[10,195,196,197,199],{},"快照测试捕获渲染组件的输出并将其与基线进行比较。将快照测试添加到 ",[77,198,131],{"code":131},"：",[160,201,202,206],{},[163,203,204],{"v-slot:title":75},[10,205,167],{},[10,207,208,209,212],{},"文件也可以是 ",[77,210,211],{"code":211},"HelloWorld.test.ts","，此时vitest也可以找到测试文件",[69,214,217],{"className":215,"code":216,"filename":131,"language":91,"meta":75},[89],"it('matches the snapshot', () => {\n    const wrapper = mount(HelloWorld);\n    expect(wrapper.html()).toMatchSnapshot();\n});\n",[77,218,216],{"__ignoreMap":75},[10,220,221],{},"Vitest 允许您模拟模块和函数。例如：",[69,223,226],{"className":224,"code":225,"filename":131,"language":91,"meta":75},[89],"vi.mock('axios', () => ({\n    default: {\n        get: vi.fn(() => Promise.resolve({ data: 'Mocked Data' }))\n    }\n}));\n",[77,227,225],{"__ignoreMap":75},[10,229,230],{},"测试组件如何处理 props 和发出事件：",[69,232,236],{"className":233,"code":234,"filename":235,"language":91,"meta":75},[89],"it('renders with props', () => {\n    const wrapper = mount(HelloWorld, {\n        props: { initialMessage: 'Hello, Props!' }\n    });\n    expect(wrapper.text()).toContain('Hello, Props!');\n});\n","NewHelloWorld.spec.ts",[77,237,234],{"__ignoreMap":75},[160,239,240,244,247,253],{},[163,241,242],{"v-slot:title":75},[10,243,167],{},[10,245,246],{},"这时，你可以改动HelloWorld.vue组件来观察测试结果",[69,248,251],{"className":249,"code":250,"filename":112,"language":119,"meta":75},[117],"\u003Cscript setup lang=\"ts\">\nimport { ref } from \"vue\"\n\nconst props = defineProps\u003C{\n    initialMessage: string\n}>()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n    \u003Cdiv>\n        \u003Ch1>{{ initialMessage }}\u003C\u002Fh1>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[77,252,250],{"__ignoreMap":75},[69,254,257],{"className":255,"code":256,"filename":235,"language":91,"meta":75},[89],"import { mount } from '@vue\u002Ftest-utils';\nimport { describe, expect, it, vi } from 'vitest';\n\nimport NewHelloWorld from '..\u002Fsrc\u002Fcomponents\u002FNewHelloWorld.vue';\n\ndescribe('NewHelloWorld.vue', () => {\n    it('renders with props', () => {\n        const wrapper = mount(NewHelloWorld, {\n            props: { initialMessage: 'Hello, Props!' }\n        });\n        expect(wrapper.text()).toContain('Hello, Props!');\n    });\n});\n",[77,258,256],{"__ignoreMap":75},[33,260,262],{"id":261},"原文之外的扩展译者注","原文之外的扩展【译者注】",[264,265,267],"h3",{"id":266},"vitestui","@vitest\u002Fui",[10,269,270],{},"Vitest 由 Vite 提供能力，在运行测试时有一个开发服务器。这允许 Vitest 提供一个漂亮的 UI 界面来查看并与测试交互。Vitest 的 UI 界面是可选的，你可以通过以下安装：",[69,272,275],{"className":273,"code":274,"language":147,"meta":75},[145],"npm i -D @vitest\u002Fui\n",[77,276,274],{"__ignoreMap":75},[10,278,279],{},"接下来，你可以通过传入 --ui 参数来启动测试的 UI 界面：",[69,281,284],{"className":282,"code":283,"language":147,"meta":75},[145],"vitest --ui\n",[77,285,283],{"__ignoreMap":75},[264,287,289],{"id":288},"vitest-in-vscode","vitest in vscode",[10,291,292,293,298],{},"当然您也可以安装",[14,294,297],{"href":295,"rel":296},"https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=vitest.explorer",[18],"vitest 扩展","在vscode中点击侧边栏进行测试，且测试结果会以icon形式展示",[33,300,301],{"id":301},"总结",[10,303,304],{},"使用 Vitest 测试 Vue 组件是一个简单且令人愉快的过程。它的速度、现代功能和无缝 Vue 集成使其成为希望确保其应用程序健壮且可维护的开发人员的绝佳选择。",[10,306,307],{},"保重，下次再见！",[10,309,310],{},"And happy coding as always 🖥️",{"title":75,"searchDepth":312,"depth":312,"links":313},4,[314,316,317,318,323],{"id":35,"depth":315,"text":36},2,{"id":63,"depth":315,"text":64},{"id":192,"depth":315,"text":193},{"id":261,"depth":315,"text":262,"children":319},[320,322],{"id":266,"depth":321,"text":267},3,{"id":288,"depth":321,"text":289},{"id":301,"depth":315,"text":301},[325],"译","2025-01-14 10:12:32",false,"md","https:\u002F\u002Fbitmc.uno\u002Fpicgo\u002Ftesting%20vue%20components%20with%20vitest.jpg",{},true,"\u002Fposts\u002F2025\u002Ftesting-vue-components-with-vitest",null,{"text":335,"minutes":336,"time":337,"words":338},"6 min read",5.11,306600,1022,1,{"title":5,"description":31},{"loc":332},"posts\u002F2025\u002Ftesting vue components with vitest",[344],"Vue","r0E9FO33B7aYNOYB1puwXJkldhafqJ8cgOX6g5su3co",[347,352],{"title":348,"path":349,"stem":350,"date":351,"type":333,"children":-1},"【翻译】前端测试指南：命名测试的 10 条基本规则","\u002Fposts\u002F2025\u002Ffrontend-testing-guide-10-essential-rules-for-naming-tests","posts\u002F2025\u002FFrontend Testing Guide - 10 Essential Rules for Naming Tests","2025-01-10 14:31:21",{"title":353,"path":354,"stem":355,"date":356,"type":333,"children":-1},"【翻译】在Vue单文件组件中使用两个script块","\u002Fposts\u002F2025\u002Fusing-two-script-blocks-in-vue-single-file-components","posts\u002F2025\u002Fusing-two-script-blocks-in-vue-single-file-components","2025-01-14 11:02:22",1789642585681]