如何正确使用Jasmine和/或Sinonunit testingjQuery的.ajax()承诺?

我有一个相当简单的函数,它返回一个jQuery .ajax()承诺如此:

CLAW.controls.validateLocation = function(val, $inputEl) { return $.ajax({ url: locationServiceUrl + 'ValidateLocation/', data: { 'locationName': val }, beforeSend: function() { $inputEl.addClass('busy'); } }).done(function(result) { // some success clauses }).fail(function(result) { // some failure clauses }).always(function() { // some always clauses }); } 

在大多数情况下,这个新的承诺接口像梦一样工作,并消除使用jQuery的.ajax()的callback金字塔是伟大的。 然而,我不能为了我的生活弄清楚如何用Jasmine和/或Sinon来正确地testing这些承诺:

  1. Sinon的所有文档都假设你正在使用旧式的callback, 我没有看到一个如何与promise / deferreds一起使用的例子

  2. 当试图用Jasmine或Sinon间谍来监视$ .ajax时,间谍正在有效地覆盖承诺,所以它的donefailalways子句不再存在于ajax函数中,所以承诺永远不会解决和抛出一个错误代替

我真的只是喜欢一个或两个如何testing这些新的jQuery .ajax()承诺与上述testing库。 我对networking的search力度相当强,而且还没有真正挖掘过这些东西。 我使用Jasmine.ajax提到的一个资源,但是如果可能的话,我想尽量避免使用Sinon提供的大部分相同的function。

4 Solutions collect form web for “如何正确使用Jasmine和/或Sinonunit testingjQuery的.ajax()承诺?”

实际上并不那么复杂。 根据您的情况返回承诺并解决问题就足够了。

例如:

 spyOn($, 'ajax').andCallFake(function (req) { var d = $.Deferred(); d.resolve(data_you_expect); return d.promise(); }); 

为了成功,还是

 spyOn($, 'ajax').andCallFake(function (req) { var d = $.Deferred(); d.reject(fail_result); return d.promise(); }); 

为失败。

对于Jasmine 2.0,语法稍有改变:

 spyOn($, 'ajax').and.callFake(function (req) {}); 

Jasmine 2.0中不存在.andCallFake()方法

一些沿着这些线/与sinon和jQuery延期

 ajaxStub = sinon.stub($, "ajax"); function okResponse() { var d = $.Deferred(); d.resolve( { username: "testuser", userid: "userid", success: true } ); return d.promise(); }; function errorResponse() { var d = $.Deferred(); d.reject({},{},"could not complete"); return d.promise(); }; ajaxStub.returns(okResponse()); ajaxStub.returns(errorResponse()); 

这是一个简单的方法与JavaScript。

 quoteSnapshots: function (symbol, streamId) { var FakeDeferred = function () { this.error = function (fn) { if (symbol.toLowerCase() === 'bad-symbol') { fn({Error: 'test'}); } return this; }; this.data = function (fn) { if (symbol.toLowerCase() !== 'bad-symbol') { fn({}); } return this; }; }; return new FakeDeferred(); } 

每个callback中的if语句都是我在testing中用来驱动成功或错误执行的东西。

如果使用像.complete()这样的东西,@ggozad给出的解决scheme将不起作用。

但是,万岁,茉莉花做了一个插件来做到这一点: http : //jasmine.github.io/2.0/ajax.html

 beforeEach(function() { jasmine.Ajax.install(); }); afterEach(function() { jasmine.Ajax.uninstall(); }); //in your tests expect(jasmine.Ajax.requests.mostRecent().url).toBe('/some/cool/url'); 
  • 如何使用ES6模块模拟unit testing的依赖关系
  • 如何使用@PathVariable对Spring MVC控制器进行unit testing?
  • 什么是嘲笑?
  • 在包装函数之前,我可以修补Python装饰器吗?
  • “创buildunit testing”select在哪里?
  • 最后的方法嘲笑
  • 我如何允许assembly(unit testing)来访问另一个assembly的内部属性?
  • angular2testing,我怎么模仿子组件
  • Unittest的assertEqual和iterables - 只检查内容
  • 在Moq Callback()调用中设置variables值
  • 如何读取/改善由PHP计算的CRAP指数