如何不使用JsDom在node环境下运行Vue.js单元测试?
核心逻辑说明
Jest将node设为默认测试环境,是面向不需要浏览器DOM API的测试场景(比如纯工具函数、接口封装、状态管理逻辑、公共方法这类不涉及组件渲染的逻辑),这类场景下node环境确实比jsdom快30%以上。
不管是Vue还是React生态,只要用到对应测试工具做组件渲染/交互测试,就必然依赖浏览器环境API,不可能完全脱离类浏览器模拟层。React社区的通用做法也是拆分测试类型,纯逻辑测试跑node,组件测试仍然使用jsdom类环境,并非所有测试都跑在纯node环境下。
你遇到的报错是Vue Test Utils的正常校验,只要你要测组件渲染逻辑,就必须有浏览器API的模拟层,不是你遗漏了配置。
可行配置方案
方案1:按测试类型拆分环境(社区首选方案)
该方案不需要修改现有组件测试逻辑,同时能让非组件测试享受到node环境的速度优势:
- 先对测试文件做分类:将不需要渲染组件的测试(比如工具函数、状态管理逻辑)统一放到
test/unit/目录,组件测试统一放到test/components/目录 - 如果你用Jest 28及以上版本,先手动安装jsdom依赖:
npm install jest-environment-jsdom --save-dev - 修改
jest.config.js,用testEnvironmentMatch给不同类型的测试文件指定对应环境:
module.exports = { // 全局默认用node环境,适配大部分非组件测试 testEnvironment: 'node', testEnvironmentMatch: [ // 组件测试自动匹配jsdom环境 ['**/test/components/**/*.test.js', 'jsdom'], // 如果你的组件测试用.spec作为后缀,可以新增匹配规则 ['**/*.spec.js', 'jsdom'] ] }
方案2:全量测试跑node环境,手动注入DOM模拟
如果你的组件测试都是非常轻量的渲染逻辑,不需要复杂浏览器API,可以手动在node环境注入全局DOM模拟:
- 安装依赖:
npm install jsdom --save-dev - 新增全局初始化文件
jest.setup.js,写入以下内容补全全局浏览器对象:
const { JSDOM } = require('jsdom'); const jsdom = new JSDOM('<!doctype html><html><body></body></html>'); global.window = jsdom.window; global.document = jsdom.window.document; global.navigator = global.window.navigator; // 按需补全Vue Test Utils需要的其他浏览器全局对象 global.HTMLElement = global.window.HTMLElement; global.Event = global.window.Event; global.localStorage = global.window.localStorage;
- 修改
jest.config.js引入初始化文件:
module.exports = { testEnvironment: 'node', setupFilesAfterEnv: ['<rootDir>/jest.setup.js'] }
注意:该方案仅适配极简组件测试场景,涉及复杂DOM操作、样式计算、浏览器特有API(比如canvas、location跳转)的测试大概率会报错,维护成本远高于方案1。
内容的提问来源于stack exchange,提问作者eXception
相关产品推荐
相关产品推荐

