我的项目中有一个方法,它接收一组promise返回方法。当第一个完成后,它会移动到下一个,依此类推。我很难确定如何对这种方法进行单元测试。
fireAllBatches: function (batchQueue, resolve, reject) {
if (batchQueue.length) {
var batch = batchQueue.pop();
// this returns a promise
googleCalendarService.fireBatch(batch)
.then(function (results) {
// when done fires the next one
this.fireAllBatches(batchQueue, resolve, reject);
}.bind(this)).catch(reject);
} else {
console.log('resolving firing of batches.');
resolve();
}
}
这是测试:
it('fireAllBatches should call fireBatch as many times as the number of the batches', function () {
spyOn(mockGoogleCalendarService, "fireBatch").and.returnValue(q.when({}));
datalayerObject.fireAllBatches([1, 2, 3, 4, 5, 6]);
expect(mockGoogleCalendarService.fireBatch).toHaveBeenCalled();
expect(mockGoogleCalendarService.fireBatch.calls.count()).toBe(6);
});
更新
调查并阅读this回答后。我能够将递归方法转换为:
fireAllBatches: function (batchQueue, resolve, reject) {
var methodArray = _.map(batchQueue, function (batch) {
return function () {
console.log('firing batch');
return googleCalendarService.fireBatch(batch)
}
});
var resolvedPromise = $q.when(true);
methodArray.reduce(function(cur, next) {
return cur.then(next);
}, resolvedPromise).then(resolve).catch(reject);
}
但是,我不确定它是否会正确捕获错误。
答案 0 :(得分:1)
这不是关于单元测试的具体答案。但是,如果你在ES6中工作,你可以沿着这些方向做一些事情来避免递归,它可能会简化你的测试:
batchQueue.reduce( (chain,batch) => {
return chain.then(googleCalendarService.fireBatch(batch))
}, Promise.resolve(null)).then(resolve).catch(reject);
答案 1 :(得分:1)
我会模拟或删除googleCalendarService.fireBatch()
函数,因此您可以验证调用它的内容,然后您可以使用间谍来解析和拒绝参数。
以下是我要测试的内容:
batchQueue
为空/未定义的情况。resolve
为空,则应立即致电batchQueue
googleCalendarService.fireBatch
存根一次,然后在传入一个队列的队列时调用resolve。googleCalendarService.fireBatch
存根两次,resolve
间谍调用一次2个队列的队列。googleCalendarService.fireBatch
函数是否抛出了reject
间谍被调用的错误。您也可以考虑其他测试。