对vue项目(增加进行)单元测试,所遇到的问题及解决方法。 dom节点为null等

xiaoxiao2025-06-02  42

1、用vue-cli生成一个新的项目,把单元测试需要的文件直接复制到你现有的项目中

2.增加启动入口

"unit": "karma start test/unit/karma.conf.js --single-run"

3.安装单元测试需要的插件

npm i -D karma karma-webpack phantomjs-prebuilt karma-phantomjs-launcher karma-phantomjs-shim karma-chrome-launcher karma-sourcemap-loader mocha karma-mocha sinon chai sinon-chai karma-sinon-chai karma-spec-reporter karma-coverage

 

4.复制vue-cli生成helloWorld.vue文件到现有项目

执行 npm run unit 

这是测试通过的截图。

 

采坑1、 网上找到解决方法

 

采坑2、运行各种出错!汗...

在karma.conf.js文件里把 PhantomJS 换为 Chrome

采坑3、点击事件及事件封装方法。

未封装前:

封装后:

封装的util.js采用elementUI项目的源码并稍微改动,如createTest函数

util.js贴在本页最底下。

 

采坑4、vm.$el.querySelector('xxx') 为 null 等情况.

vm.$el为本组件的dom节点,只能获取组件内的dom

全局弹窗等在组件外生成dom,需要从document/html下获取对应dom

如有引入element等第三方插件,需要引入

最后建议:github上下载elementUI项目的源码进行参考。

util.js:

import Vue from 'vue'; import ElementUI from 'element-ui'; Vue.use(ElementUI); let id = 0; const createElm = function() { const elm = document.createElement('div'); elm.id = 'app' + ++id; document.body.appendChild(elm); return elm; }; /** * 回收 vm * @param {Object} vm vm */ const destroyVM = function(vm) { vm.$destroy && vm.$destroy(); vm.$el && vm.$el.parentNode && vm.$el.parentNode.removeChild(vm.$el); }; /** * 创建一个 Vue 的实例对象 * @param {Object|String} Compo 组件配置,可直接传 template * @param {Boolean=false} mounted 是否添加到 DOM 上 * @return {Object} vm */ const createVue = function(Compo, mounted = false) { if (Object.prototype.toString.call(Compo) === '[object String]') { Compo = { template: Compo }; } return new Vue(Compo).$mount(mounted === false ? null : createElm()); }; /** * 创建一个测试组件实例 * @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components * @param {Object} Compo - 组件对象 * @param {Object} propsData - props 数据 * @param {Boolean=false} mounted - 是否添加到 DOM 上 * @return {Object} vm */ const createTest = function(Compo, propsData = {}, mounted = false) { if (propsData === true || propsData === false) { mounted = propsData; propsData = {}; } const elm = createElm(); const Ctor = Vue.extend(Compo); return new Ctor({ propsData }).$mount(mounted === false ? null : elm); }; /** * 触发一个事件 * mouseenter, mouseleave, mouseover, keyup, change, click 等 * @param {Element} elm * @param {String} name * @param {*} opts */ const triggerEvent = function(elm, name, ...opts) { let eventName; if (/^mouse|click/.test(name)) { eventName = 'MouseEvents'; } else if (/^key/.test(name)) { eventName = 'KeyboardEvent'; } else { eventName = 'HTMLEvents'; } const evt = document.createEvent(eventName); evt.initEvent(name, ...opts); elm.dispatchEvent ? elm.dispatchEvent(evt) : elm.fireEvent('on' + name, evt); return elm; }; /** * 触发 “mouseup” 和 “mousedown” 事件 * @param {Element} elm * @param {*} opts */ const triggerClick = function(elm, ...opts) { exports.triggerEvent(elm, 'mousedown', ...opts); exports.triggerEvent(elm, 'mouseup', ...opts); return elm; }; /** * 触发 keydown 事件 * @param {Element} elm * @param {keyCode} int */ const triggerKeyDown = function(el, keyCode) { const evt = document.createEvent('Events'); evt.initEvent('keydown', true, true); evt.keyCode = keyCode; el.dispatchEvent(evt); }; export { destroyVM, createVue, createTest, triggerEvent, triggerClick, triggerKeyDown };

 

转载请注明原文地址: https://www.6miu.com/read-5031129.html

最新回复(0)