http://shaynegui.com/javascript-unit-test-sinonjs/
当我们需要测试的某个方法中,需要去某个接口发送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就像一个方法的存根或者树桩,我们可以预设定一些行为给它,然后进行测试
"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
//预先设定了这些行为,我们就可以来测试我们代码的其他逻辑
}
sinon.stub(jQuery, "each").callsArgWith(1, {}).returns({});
//我们要测试$.each方法,它的参数中第0索引参数表示集合,第1个索引参数是一个回调函数,当它被调用的时候,会以callsArgWith方法的第二参数作为参数,并且返回一个空对象
"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对象就像是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一样运作
Sinon的mocks支持了spy和stub的接口,尽管spy的接口比起mocks的接口来说没那么有趣。通常前期你会使用如下的方法来设置期望。注意这些方法也会返回expectation,这样你可以使用链式调用,符合声明使得代码可读性更高
restore方法可以用来还原stub和mock的默认行为,即让测试方法变成原来该做的事情