[英]Jasmine: Calling then in AngularJS Promise
我的AngularJS控制器具有以下功能:
service.getPlaceByAddress = function(address) {
return $q(function(resolve, reject) {
geocoder().geocode({'address': address}, function(result, status) {
// gets called
if (status === google.maps.GeocoderStatus.OK) {
return resolve(result);
}
return reject();
});
});
};
我想测试这段代码,但是then函数不会被调用。 但是地址解析功能肯定会被调用。
it('returns an error if the data service returns no results', function(done) {
GoogleMaps.getPlaceByAddress('Testlocation').then(function() {
done();
// gets never called
});
$scope.$digest();
});
相反,我得到一个异步超时:
错误:超时-jasmine.DEFAULT_TIMEOUT_INTERVAL指定的超时内未调用异步回调。
编辑
当我直接返回resolve
,它可以按预期工作:
service.getPlaceByAddress = function(address) {
return $q(function(resolve, reject) {
return resolve();
//geocoder()...
});
};
因此,我认为问题出在地址解析器的回调中。 这很奇怪,因为代码可以在浏览器中完美地运行,但不能在茉莉花测试中...
我认为问题在于您正在调用真正的异步服务,而不是在单元测试中将其虚拟化。 如果您有一个虚拟服务立即完成承诺,则测试只需调用$scope.$digest()
一次即可触发then()
回调,但是如果它是真正的异步调用,则摘要将在远程服务器有机会实际发送回任何数据。
最好的解决方案是虚拟掉测试的异步部分。 因此,在此测试中,您将放置geocoder().geocode()
的存根,将其与TestLocation
作为参数一起调用时,仅会立即成功完成,失败或对每个代码进行测试。
或者,您可以有一个循环,等待直到请求确实有机会完成为止,但这对于单元测试来说是不好的样式,因为它们应该是独立的并且不依赖于远程服务器。
根据您的评论:
您链接的博客文章显示了如何模拟对Geocoder的调用,但是在该博客文章中,它只是验证是否已调用geocoder方法,实际上并没有在测试服务承诺是否得到解决以及所使用的间谍程序是否在测试中。只是返回一个不会触发回调的值。
因此,我认为您需要以他们所做的为基础:添加一个实际上会触发回调的间谍,但是与promises相关的一切都是异步的,因此您将需要调用$digest()
来强制完成promise。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.