js单元测试sinonjs库
2016-04-16 02:00
591 查看
http://shaynegui.com/javascript-unit-test-sinonjs/
提高测试效率
提升代码质量
能够及时重构代码,减少依赖项
更好的理解需求和业务逻辑,因为每一个测试可能对应一个测试用例
好的测试代码可读性强,新人也能很好的通过测试代码了解到需求,减少维护成本
当我们需要测试的某个方法中,需要去某个接口发送http请求获得数据,如果你真实的发送某个请求,那么当有一天你请求的这个服务器挂掉的时候,你的单元测试就怎么也跑不过了,其实我们要测试的时候我们这个方法针对数据库的其他处理逻辑,我们并不是真的关心这个接口是否存在(甚至是否实现),那我们需要模拟一个这样的接口来返回假的数据,sinonjs就是为了解决这个问题的
以上代码就是模拟了ajax请求,而不会真正的发送一个xmlhttprequest出去,我们只是模拟了它返回的数据和一些行为,方便我们测试其他的逻辑
stub就像一个方法的存根或者树桩,我们可以预设定一些行为给它,然后进行测试
withArgs().returns()一般用来使用在同步的代码中
callsArgWith用来测试你需要测试的某个方法拥有一个或者多个回调,callsArgWith的第一个参数表示你要模拟第一个回调,它是个索引值,后面的参数就是你要测试回调的参数
yieldsTo一般用在你的测试函数的参数是一个对象,这个对象有很多属性,其中你要测试某一个属性,而刚好这个属性是一个函数
更多用法请参考sinojs的文档
mock更侧重与是测试代码是否作出了行为,Mock对象就像是stubs和spies的组合,并且内建了预编码地验证行为,也被成为期望。Mocks会在前期设置它们的期望(而不会像我们常见的断言一样在执行后判断是否符合期望)并且在接收到不被期望的调用时立即失败。最终mock.verify()的调用会验证所有的期望是否符合
如果mock被调用了超过一次,这个测试会立马失败。当verify()被调用时,如果mock没有被调用过则会抛出一个exception
也可以为一个对象上的方法创建mock,这就和spies和stubs一样。接口稍微有些不同,我们需要创建:一个mock对象和设置我们想要给于期望的方法
Sinon的mocks支持了spy和stub的接口,尽管spy的接口比起mocks的接口来说没那么有趣。通常前期你会使用如下的方法来设置期望。注意这些方法也会返回expectation,这样你可以使用链式调用,符合声明使得代码可读性更高
execptation.atLeast(callCount) 确保mock的被调用次数达到指定的次数
expectation.atMost(callCount)确保mock的被调用次数不会超过指定的次数
expectation.exactly(callCount)指定mock被调用的次数。
expectation.never()exactly(0)的快捷方法。
expectation.once()exactly(1)的快捷方法。
expectation.twice()exactly(2)的快捷方法。
expectation.thrice()exactly(3)的快捷方法。
expectation.withArgs(arg1, arg2, ...)就像spy的calledWith(arg1, arg2, ...)方法一样,只不过是它是用作前期对期望的设置。
expectation.withExactArgs(arg1, arg2, ...)就像spy的calledWithExactly(arg1, arg2, ...)方法一样,只不过是它是用作前期对期望的设置。
expectation.on(thisObj)期望this值匹配指定的对象
restore方法可以用来还原stub和mock的默认行为,即让测试方法变成原来该做的事情
单元测试的意义
提高测试效率提升代码质量
能够及时重构代码,减少依赖项
更好的理解需求和业务逻辑,因为每一个测试可能对应一个测试用例
好的测试代码可读性强,新人也能很好的通过测试代码了解到需求,减少维护成本
sinonjs就是这样一套面向js的单元测试辅助库
当我们需要测试的某个方法中,需要去某个接口发送http请求获得数据,如果你真实的发送某个请求,那么当有一天你请求的这个服务器挂掉的时候,你的单元测试就怎么也跑不过了,其实我们要测试的时候我们这个方法针对数据库的其他处理逻辑,我们并不是真的关心这个接口是否存在(甚至是否实现),那我们需要模拟一个这样的接口来返回假的数据,sinonjs就是为了解决这个问题的{ setUp: function () { sinon.spy(jQuery, "ajax"); }, tearDown: function () { jQuery.ajax.restore(); // Unwraps the spy }, "test should inspect jQuery.getJSON's usage of jQuery.ajax": function () { jQuery.getJSON("/some/resource"); assert(jQuery.ajax.calledOnce); assertEquals("/some/resource", jQuery.ajax.getCall(0).args[0].url); assertEquals("json", jQuery.ajax.getCall(0).args[0].dataType); } }
以上代码就是模拟了ajax请求,而不会真正的发送一个xmlhttprequest出去,我们只是模拟了它返回的数据和一些行为,方便我们测试其他的逻辑
stub的用法
stub就像一个方法的存根或者树桩,我们可以预设定一些行为给它,然后进行测试"test should stub method differently based on arguments": function () { var callback = sinon.stub();//创建一个stub对象 callback.withArgs(42).returns(1);//当调用参数为42的时候返回1 callback.withArgs(1).throws("TypeError");//当调用参数为1的时候抛出一个异常 callback(); // No return value, no exception callback(42); // Returns 1 callback(1); // Throws TypeError //预先设定了这些行为,我们就可以来测试我们代码的其他逻辑 }
stub的api的一些使用场景
withArgs().returns()一般用来使用在同步的代码中callsArgWith用来测试你需要测试的某个方法拥有一个或者多个回调,callsArgWith的第一个参数表示你要模拟第一个回调,它是个索引值,后面的参数就是你要测试回调的参数
sinon.stub(jQuery, "each").callsArgWith(1, {}).returns({}); //我们要测试$.each方法,它的参数中第0索引参数表示集合,第1个索引参数是一个回调函数,当它被调用的时候,会以callsArgWith方法的第二参数作为参数,并且返回一个空对象
yieldsTo一般用在你的测试函数的参数是一个对象,这个对象有很多属性,其中你要测试某一个属性,而刚好这个属性是一个函数
"test should fake successful ajax request": function () { sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]); //要模拟success函数,同时传入一个数组给success函数当作参数 jQuery.ajax({ success: function (data) { assertEquals([1, 2, 3], data); } }); }
更多用法请参考sinojs的文档
mock的用法
mock更侧重与是测试代码是否作出了行为,Mock对象就像是stubs和spies的组合,并且内建了预编码地验证行为,也被成为期望。Mocks会在前期设置它们的期望(而不会像我们常见的断言一样在执行后判断是否符合期望)并且在接收到不被期望的调用时立即失败。最终mock.verify()的调用会验证所有的期望是否符合"test should call event handler": function () { var mock = sinon.mock(); var myElement = document.getElementsByTagName("a")[0]; dom.addEventListener(myElement, "mouseover", mock); dom.fireEvent(myElement, "mouseover"); mock.verify(); }
如果mock被调用了超过一次,这个测试会立马失败。当verify()被调用时,如果mock没有被调用过则会抛出一个exception
也可以为一个对象上的方法创建mock,这就和spies和stubs一样。接口稍微有些不同,我们需要创建:一个mock对象和设置我们想要给于期望的方法
var mock = sinon.mock(jQuery); mock.expects("each").once().callsArgWith(1, {}).returns({}); //代码创建了jQuery.each方法的期望:只被调用一次,并且指示它向之前的stub一样运作
mock的期望
Sinon的mocks支持了spy和stub的接口,尽管spy的接口比起mocks的接口来说没那么有趣。通常前期你会使用如下的方法来设置期望。注意这些方法也会返回expectation,这样你可以使用链式调用,符合声明使得代码可读性更高execptation.atLeast(callCount) 确保mock的被调用次数达到指定的次数
expectation.atMost(callCount)确保mock的被调用次数不会超过指定的次数
expectation.exactly(callCount)指定mock被调用的次数。
expectation.never()exactly(0)的快捷方法。
expectation.once()exactly(1)的快捷方法。
expectation.twice()exactly(2)的快捷方法。
expectation.thrice()exactly(3)的快捷方法。
expectation.withArgs(arg1, arg2, ...)就像spy的calledWith(arg1, arg2, ...)方法一样,只不过是它是用作前期对期望的设置。
expectation.withExactArgs(arg1, arg2, ...)就像spy的calledWithExactly(arg1, arg2, ...)方法一样,只不过是它是用作前期对期望的设置。
expectation.on(thisObj)期望this值匹配指定的对象
restore方法可以用来还原stub和mock的默认行为,即让测试方法变成原来该做的事情
相关文章推荐
- 用Javascript检测浏览器音频支持情况
- js的一套日期控件简单版
- JavaScript模板引擎
- javascript的闭包和匿名函数
- js断点调试心得
- JSP取得绝对路径
- 如何将js获取的变量付给jsp中表单的action
- js实现的老黄历项目总结
- jy901 ajson树莓派上编译错误
- js去除字符串中所有html标签及 符号
- JS学习 第一天--
- JS继承
- 使用文件流ADS 及 JavaScript 进行钓鱼攻击
- 【BZOJ1561】[JSOI2009]去括号【表达式相关】
- JSONModel, 解析
- 面向对象在javascript中的三大特征之封装
- javascript中面向对象的三大作用
- js正则表达式
- JS实现《黑客帝国》落地字母背景
- js事件的相关收集