使用mocha集成单元测试(上)项目地址:https://github.com/Jay-tian/j...安装依赖yarnaddjquerymochamochawesomeistanbulsinonchaijsdomdecachebabel-clibabel-corebabel-preset-es2015babel-plugin-module-resolverbabel-istanbulmocha:测试框架mochawesome:visualreportistanbul:coveragesinon:replacedependencieschai:assertscriptscommandcommand"scripts":{"test":"mocha--timeout5000--递归--reportermochawesome--requirebabel-core/registertests/src&&打开mochawesome-report/mochawesome.html&&npmruntest:cover","test:cover":"babel-node./node_modules/.bin/babel-istanbulcover_mocha--tests/src/*-Rspec--recursive&&opencoverage/lcov-report/index.html","test:s":"mocha--recursive--requirebabel-core/注册--timeout5000"}test命令:执行单元测试,并打开测试报告页面和覆盖率页面test:cover执行生成单元测试覆盖率并打开test:s执行单个单元测试文件参数分析--timeout5000超时设置--recursive包含子目录--reportermochawesome通过mochawesome生成报告--requirebabel-core/register通过babel单元测试目录路径openmochawe翻译es6语法tests/srcsome-report/mochawesome.html打开页面测试包含jQuery的代码初始化Jquery环境let{JSDOM}=require('jsdom');letdom=newJSDOM(`
`,{url:'http://127.0.0.1',referrer:'http://127.0.0.1',contentType:'text/html',userAgent:'Mellblomenator/9000',includeNodeLocations:true,});global.window=dom.window;global.$=require('jquery');测试点击事件const{demo1}=require('../../src/demo1.js');constassert=require('chai').assert;describe('demo1',function(){it('jqueryclicktest',function(){demo1($('??body'));assert.equal($('body').hasClass('hide'),false);$('body').trigger('click');assert.equal($('body').hasClass('hide'),true);});});运行结果上面的测试,当点击一个元素的时候,给元素添加一个'hide'类方法来模拟jquery环境并触发click事件来测试post事件由于jquery环境的初始化比较常见,我们把它在工具类中引用utils.jsconstdecache=require('decache');let{JSDOM}=require('jsdom');exports.initJquery=function(html,params={}){params=Object.assign({url:'http://127.0.0.1',referrer:'http://127.0.0.1',contentType:'text/html',userAgent:'Mellblomenator/9000',includeNodeLocations:true,},参数);letdom=newJSDOM(`${html}`,参数);global.window=dom.window;decache('jquery');global.$=require('jquery');}因为在node环境下,require会有缓存,导致不同单元测试之间初始环境不一致,需要手动清除缓存decache('jquery');test.demo2.js从'../../src/demo2.js'导入帖子;constutils=require('./../utils');constsinon=require('sinon');require('./../utils');describe('demo2',function(){before(function(){utils.initJquery('');});it('jquerypost',function(){让stubPost=sinon.stub($,'post');让expectedUrl='/demo2';让expectedParams={'a':'abc'};post();sinon.assert.calledWith(stubPost,expectedUrl,expectedParams);tubPost.restore();});});restore()操作将恢复被替换的对象mocha有四个钩子方法beforerunoncebeforeallunittestsrunafterrunonceafterallunittestrunsbeforeEachRunoncebeforeeachunittestrunafterEachjsexport默认函数(){$.ajax({type:'GET',url:null,async:true,promise:true,dataType:'json',beforeSend(request){}});}test.demo3.jsimport来自'../../src/demo3.js'的ajax;constutils=require('./../utils');constsinon=require('sinon');要求('./../utils');describe('demo3',function(){before(function(){utils.initJquery('');});it('jqueryajax',function(){letstubAjax=sinon.stub($,'ajax');letexpectedParams={type:'GET',url:null,async:true,promise:true,dataType:'json'};ajax();sinon.assert.calledWithMatch(stubAjax,expectedParams);stubAjax.restore();});});这里我们使用calledWithMatch断言参数,可以断言输入参数是否正确,不需要传入所有参数来测试异步代码demoe4.jsexportdefaultfunction(){$('#demo4').hide();setTimeout(function(){$('#demo4').show();},1000);}从'../../src/demo4.js'导入demo4;constutils=require('./../utils');constsinon=require('sinon');constassert=require('chai').assert;require('./../utils');describe('异步代码',function(){letclock;before(function(){utils.initJquery('