sinon

需要测试的代码


functiononce(fn){varreturnValue,called=false;returnfunction(){if(!called){called=true;returnValue=fn.apply(this,arguments);}returnreturnValue;};}


间谍(spy)

用spy测试上面的函数:

it("calls the original function",function(){varcallback=sinon.spy();varproxy=once(callback);proxy();assert(callback.called);});

sinon.spy进行绑定。

once(callback) 绑定回调函数。

assert(callback.called) 断言。

下面这段代码判定函数被调用了一次:

it("calls the original function only once",function(){varcallback=sinon.spy();varproxy=once(callback);proxy();proxy();assert(callback.calledOnce);// ...or:// assert.equals(callback.callCount, 1);});

也可以对实体和参数进行断言:

it("calls original function with right this and args",function(){varcallback=sinon.spy();varproxy=once(callback);varobj={};proxy.call(obj,1,2,3);assert(callback.calledOn(obj));assert(callback.calledWith(1,2,3));});


Stubs(桩??)

it("returns the return value from the original function",function(){varcallback=sinon.stub().returns(42);varproxy=once(callback);assert.equals(proxy(),42);});

sinon.stub().returns(42) 对stub进行绑定。当调用stub的时候返回42。

assert.equals(proxy(), 42) 执行proxy() 并判定返回的是不是42.


测试Ajax

待测试的方法:

functiongetTodos(listId,callback){jQuery.ajax({url:"/todo/"+listId+"/items",success:function(data){// Node-style CPS: callback(err, data)callback(null,data);}});}

当执行getTodos方法的时候跳转到url指定的地址并且返回callback函数。

为了判定是否正确绑定url我们对jQuery.ajax打个桩。

after(function(){// When the test either fails or passes, restore the original// jQuery ajax function (Sinon.JS also provides tools to help// test frameworks automate clean-up like this)jQuery.ajax.restore();});it("makes a GET request for todo items",function(){sinon.stub(jQuery,"ajax");getTodos(42,sinon.spy());assert(jQuery.ajax.calledWithMatch({url:"/todo/42/items"}));});

after 方法是为了当测试方法执行完之后jquery.ajax()方法复原,不会对原来的代码产生影响。

这里存在一个疑问:如果原方法中没有callback参数,如何进行spy???


虚拟 XMLHTTP请求

模拟 xmlhttp请求:

varxhr,requests;before(function(){xhr=sinon.useFakeXMLHttpRequest();requests=[];xhr.onCreate=function(req){requests.push(req);};});after(function(){// Like before we must clean up when tampering with globals.xhr.restore();});it("makes a GET request for todo items",function(){getTodos(42,sinon.spy());assert.equals(requests.length,1);assert.match(requests[0].url,"/todo/42/items");});

before方法在正式测试之前进行一系列的准备工作:模拟http请求,并发送请求。

it中执行方法并断言。请注意这个地方,前面用的是stub方法,绑定后执行ajax。而在这里是在before里面调用了ajax(一开始我没看出来)。

分析:在运行之前开始ajax的调用,当运行到gettodos方法的时候调用ajax执行gettodos里面的jquery.ajax方法,如果没有xhr.onCreate的话就不会有ajax请求也就不会调用ajax方法了。然后通过sinon.spy()进行断言。

after方法恢复原来所有的更改。


模拟 服务

(相对于前面的模拟request请求)

此部分模拟了后台的服务,不用跳转到后台进行执行了:

varserver;before(function(){server=sinon.fakeServer.create();});after(function(){server.restore();});it("calls callback with deserialized data",function(){varcallback=sinon.spy();getTodos(42,callback);// This is part of the FakeXMLHttpRequest APIserver.requests[0].respond(200,{"Content-Type":"application/json"},JSON.stringify([{id:1,text:"Provide examples",done:true}]));assert(callback.calledOnce);});

执行测试之前模拟服务端,相当于服务端开启

sinon.spy()监听。

执行getTodos()方法。用模拟的server服务返回需要的参数。然后断言方法是否执行一次

执行完恢复为原来的状态。

那什么模拟时间的是什么乱七八糟的东西,你们自己看吧,用到的应该比较少。OK,搞定收工~

自己乱写的,不喜勿喷~

你可能感兴趣的:(sinon)