我有一个相当简单的函数,它返回一个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
});
}
在大多数情况下,这个新的promises接口就像一个梦想,当使用jQuery的.ajax()时,消除回调金字塔非常棒。但是,我不能为我的生活弄清楚如何使用Jasmine和/或Sinon正确测试这些承诺:
所有Sinon的文档都假设您使用的是旧式学校 回调;我没有看到如何使用它的单一示例 许/ deferreds
当试图使用Jasmine或Sinon间谍监视$ .ajax时,
间谍有效地覆盖了承诺,所以done
,fail
,
ajax函数中不再存在always
子句,因此承诺永远不会解决并抛出错误
我真的很喜欢一个或两个如何使用前面提到的测试库测试这些新的jQuery .ajax()promises的例子。我已经相当强烈地搜索了'网,并没有真正挖掘任何东西这样做。我找到的一个资源是使用Jasmine.ajax提到的,但我想尽可能避免这种情况,因为Sinon提供了大部分开箱即用的相同功能。
答案 0 :(得分:106)
实际上并不复杂。只需返回一个承诺并根据您的情况解决它。
例如:
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()方法
答案 1 :(得分:16)
沿着这些方面的东西/与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());
答案 2 :(得分:0)
这是一个简单的方法,仅使用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();
}
每个回调中的if语句都是我在测试中用来驱动成功或错误执行的。
答案 3 :(得分:0)
如果您使用.complete()
之类的内容,@ ggozad提供的解决方案将无效。
但是,讽刺的是,jasmine做了一个插件来完成这个: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');