Angularjs 角度及;Jasmine:如何测试$q承诺链是否已解决
我有一个服务,它公开一个函数,该函数接收解析的CSV(使用),并承诺反映解析状态:Angularjs 角度及;Jasmine:如何测试$q承诺链是否已解决,angularjs,jasmine,promise,angular-promise,Angularjs,Jasmine,Promise,Angular Promise,我有一个服务,它公开一个函数,该函数接收解析的CSV(使用),并承诺反映解析状态: 如果文件缺少必填字段,则承诺将被拒绝 否则,它会将每一行解析为一个项目,并自动填充缺少的字段(自动填充过程是异步的)。 填充所有项后,函数将使用项数组解析承诺 我要测试的函数是onCsvParse: angular.module('csvParser', []) .factory('csvParser', ['$http', function($http) { var service =
如果文件缺少必填字段,则承诺将被拒绝
否则,它会将每一行解析为一个项目,并自动填充缺少的字段(自动填充过程是异步的)。
填充所有项后,函数将使用项数组解析承诺 我要测试的函数是onCsvParse:
angular.module('csvParser', [])
.factory('csvParser', ['$http',
function($http) {
var service = {
onCsvParse: function(results, creatingBulkItems) {
var errors = this.getCsvErrors(results);
if (errors.length > 0) {
//reject
creatingBulkItems.reject(errors);
} else {
var items = this.parseCsv(results);
var autoPopulateItems = [],
populatedItems = [];
for (var i = 0; i < populatedItems.length; i++) {
var item = items[i];
if (item.name === "" /*or some any field is missing */ ) {
// auto populate item
autoPopulateItems.push(this.autoPopulateItem(item));
} else {
var populatedItem = $q.when(item);
populatedItems.push(populatedItem);
}
}
populatedItems =autoPopulateItems.concat(populatedItems);
var populatingAllItems = $q.all(populatedItems);
populatingAllItems.then(function(items) {
creatingBulkItems.resolve(items);
}, function(err) {
creatingBulkItems.resolve(err);
});
}
},
autoPopulateItem: function(newItem) {
var populatingItem = $q.defer();
var item = angular.copy(newItem);
$http.post('api/getItemData', { /*.....*/ })
.success(function(response) {
//----Populate item fields
item.name = response.name;
//....
//resolve the promise
populatingItem.resolve(item)
}).error(err) {
// resolving on error for $q.all indication
populatingItem.resolve(item)
};
return populatingItem.promise;
}
}
return service;
}
])
这样我得到了一个错误:error:Timeout-Async回调没有在jasmine.DEFAULT\u Timeout\u INTERVAL指定的超时内调用
虽然我调用了$rootScope.$apply(),而且我也没有调用真正的异步调用(只调用mock,除了$q.all),但承诺没有得到解决。
如何使其工作?无效语法。您需要将函数传递给
错误
回调
}).error(function(err) {
// resolving on error for $q.all indication
populatingItem.resolve(item)
});
return populatingItem.promise;
此外,jasime测试还需要一些初始化:
读完这篇文章后:我发现了我的问题。
关键点是使用承诺展平承诺链,然后返回值 此[promise.then]函数应返回一个新的承诺,该承诺在给定的fulfilledHandler或errorHandler回调完成时实现。这允许promise操作链接在一起。回调处理程序返回的值是返回的承诺的实现值。如果回调抛出错误,则返回的承诺将移至失败状态 不是在内部承诺成功/失败回调中解析外部承诺,而是在内部承诺中解析外部承诺。然后在回调中解析外部承诺 所以我的解决方案是这样的:
onCsvParse: function(results) {
var errors = this.getCsvErrors(results);
if (errors.length > 0) {
var deferred = $q.defer();
//reject
return deferred.reject(errors);
} else {
var items = this.parseCsv(results);
var autoPopulateItems = [],
populatedItems = [];
for (var i = 0; i < populatedItems.length; i++) {
var item = items[i];
if (item.name === "" /*or some any field is missing */ ) {
// auto populate item
autoPopulateItems.push(this.autoPopulateItem(item));
} else {
var populatedItem = $q.when(item);
populatedItems.push(populatedItem);
}
}
populatedItems = autoPopulateItems.concat(populatedItems);
var populatingAllItems = $q.all(populatedItems);
return populatingAllItems.then(function(items) {
return items;
}, function(err) {
return err;
});
}
},
注意:此代码工作正常,我可以浏览csv,将其解析为项目并自动填充,问题在于测试该功能。我试图在这里只留下相关的代码,因此可能会有小的复制粘贴错误。我看不出您自己的角度服务与尝试测试和在线解析之间有任何关联service@yarons根据给出的代码,答案是“不”,我不小心删除了上面的评论。您是否将工厂注入到测试脚本中?我没有复制所有代码,因为我认为这与此无关:Papa-我在问题中提到的papaparse库getCsvErrors-也与此无关,因为我专注于解析过程。完整代码将csv解析为项目properly@AdiV发布您知道不正确的代码不是提问的好方法。@Michael此Plunker不可用。
onCsvParse: function(results) {
var errors = this.getCsvErrors(results);
if (errors.length > 0) {
var deferred = $q.defer();
//reject
return deferred.reject(errors);
} else {
var items = this.parseCsv(results);
var autoPopulateItems = [],
populatedItems = [];
for (var i = 0; i < populatedItems.length; i++) {
var item = items[i];
if (item.name === "" /*or some any field is missing */ ) {
// auto populate item
autoPopulateItems.push(this.autoPopulateItem(item));
} else {
var populatedItem = $q.when(item);
populatedItems.push(populatedItem);
}
}
populatedItems = autoPopulateItems.concat(populatedItems);
var populatingAllItems = $q.all(populatedItems);
return populatingAllItems.then(function(items) {
return items;
}, function(err) {
return err;
});
}
},
it('Should not fail :)', function(done) {
csvParser.onCsvParse(csvResults).then(function(items) {
//promise is resolved
expect(items).not.toBeNull();
done();
}, function() {
//promise is rejeceted
//expect(1).toEqual(1);
done();
});
$rootScope.$apply();});