使用Sinon.js并阻止对我的应用服务器的调用

问题很简单:

我希望我们sinon.js测试一段javascript以确保它在做两件事时调用$.ajax方法:

  1. 我不想真正打到服务器
  2. 我想模拟服务器的响应

所以这是JS:

  $.ajax url: "/tickets/id.json" dataType: 'json' .done (data) => HandlebarsTemplates["tickets/popup_title"] data 

这是我的测试:

 describe 'PopupDisplayer', -> beforeEach -> loadFixtures 'popup_displayer' new PopupDisplayer @title_stub = sinon.stub( HandlebarsTemplates, "tickets/popup_title") @jquery_stub = sinon.stub(jQuery, 'ajax').yieldsTo('done', {}) //This triggers the ajax call $('.popupable .title').mouseenter() afterEach -> HandlebarsTemplates['tickets/popup_title'].restore() HandlebarsTemplates['tickets/popup_content'].restore() jQuery.ajax.restore() @server.restore() it 'renders the title with the data returned from the server', -> expect(@title_stub).toHaveBeenCalledWith( {}) 

此测试失败,但有以下exception:

 TypeError: ajax expected to yield to 'done', but no object with such a property was passed. Received [[object Object]] 

所以我想我想知道我是否可以模拟一个jQuery请求来获得一个可以成功响应.done调用的响应,显然我不太了解defferedObject()

要模拟服务器的响应,您需要存根$.ajax的返回值:

  ... @jquery_stub = sinon.stub(jQuery, 'ajax').returns done: (callback) -> callback {...} # your object here ... 

请注意,这只会对done回调进行存根。 如果你想测试其他行为,你可能需要实现其他处理程序( failthen等)。

您还可以返回实际的jQuery Deferred对象:

  ... @deferred = new jQuery.Deferred @jquery_stub = sinon.stub(jQuery, 'ajax').returns(deferred) ... 

在这种情况下,您必须在进行测试之前显式触发返回的Deferred:

  ... @deferred.resolveWith(null, [{}]) # your object here ...