Promises:对一个递归方法进行单元测试,该方法在队列中一个接一个地触发promise

Promises: Unit testing a recursive method that fires promises in a queue one after the other

本文关键字:一个 队列 方法 promise 单元测试 递归方法 Promises      更新时间:2023-09-26

我在我的项目中有一个方法,它接收一组承诺返回方法。当第一个完成后,它会移动到下一个,以此类推。我很难弄清楚如何对这个方法进行单元测试。

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);
});

在调查和阅读了这个答案之后。我能够将递归方法转换为:

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);
}

但是,我不确定它是否能正确捕获错误。

这不是关于单元测试的具体答案。然而,如果你在ES6中工作,你可以做一些类似这样的事情来避免递归,这可能会简化你的测试:

batchQueue.reduce( (chain,batch) => {
    return chain.then(googleCalendarService.fireBatch(batch))
}, Promise.resolve(null)).then(resolve).catch(reject);

我将模拟或存根googleCalendarService.fireBatch()函数,因此您可以验证调用它的内容,然后您可以使用间谍来解析和拒绝参数。

下面是我要测试的内容:
  • (可选)考虑batchQueue为null/undefined的情况。
  • 如果batchQueue为空,应立即调用resolve
  • 它应该调用googleCalendarService.fireBatch存根一次与第一批,然后调用resolve如果你传入一个队列与一个批。
  • 对于两个批次的队列,它应该调用googleCalendarService.fireBatch stub两次,resolve spy一次。
  • 测试googleCalendarService.fireBatch函数是否抛出错误,reject间谍被调用。

您还可以考虑其他测试