Javascript单元同步测试Promise.all

时间:2016-07-20 18:04:20

标签: javascript node.js unit-testing promise sinon

我有一个node.js应用程序,其中我有一个维护状态的对象和一个每30秒更新一次这种状态的更新循环。基本上它是一个构建监视器,它在向前端提供每个管道的最新状态时查询构建机器。

在更新循环中,我需要进行多次调用,为此我需要所有数据来从中进行任何有用的操作。目前,我将所有这些调用包装在Promise中,并使用Promise.all等待它们全部完成。

在测试中,我与sinon-stub-promise包同步解析每个promise。这适用于单一承诺。然而问题是它对Promise.all不起作用 - 至少是同步的。如果我在测试中放了一个小超时,那么它就可以正常通过。

以下是一些片段:

var pipelineRequests = pipelineNames.map(function(pipelineName) {
    return gocdClient.getPipelineStatus(pipelineName);
});

Promise.all(pipelineRequests)
    .then(function(values) {
        values.forEach(function(value) {
            // Do something now all data is available
        });
    });

所以这里我得到一个pipelinesNames列表,然后创建一个请求,为每个管道返回一个promise。这在我手动测试时有效。

现在输入测试代码:

it("should wait for all to return before processing", function() {
        allPipelinesStub
            .returnsPromise().resolves({"NFT-Suite": ["Hour", "Overnight", "Weekend"]});

        pipelineStatusStub
            .withArgs("Hour")
            .returnsPromise().resolves({"status": "Passed", "build-number": 1, "upstream": ["GIT"]});

        pipelineStatusStub
            .withArgs("Overnight")
            .returnsPromise().resolves({"status": "Passed", "build-number": 1, "upstream": ["GIT"]});

        pipelineStatusStub
            .withArgs("Weekend")
            .returnsPromise().resolves({"status": "Passed", "build-number": 1, "upstream": ["GIT"]});

        var pipelinesService = require('../../src/services/pipelinesService');

        var pipelines = pipelinesService.getPipelines();
        should.exist(pipelines);
        pipelines.should.deep.equal({
            "NFT-Suite": {
                "Hour": {
                    "status": "Passed",
                    "build-number": 1,
                    "order": 0
                },
                "Overnight": {
                    "status": "Passed",
                    "build-number": 1,
                    "order": 0
                },
                "Weekend": {
                    "status": "Passed",
                    "build-number": 1,
                    "order": 0
                }
            }
        });
    });

问题是pipelines{}。如果在稍有延迟后拨打电话pipelinesService.getPipelines();,则可以正常使用。

单独测试这些是很好的,因为存根同步解析,我无法找到一种方法来强制Promise.all在完成后解析。

有没有办法强迫这个?或者我可以使用sinon(或其他东西)来解决这个问题吗?

感谢任何帮助

1 个答案:

答案 0 :(得分:0)

您需要确定要测试的内容。如果要使用Promise.all测试代码,则需要返回Promise-至少返回 some Promise表示操作已完成。这并不意味着您已经从现有代码中返回承诺:您可以将逻辑包装在另一个私有函数“ _foo”中,然后让现有代码使用该逻辑,然后测试“ foo”。而不是原始代码。

如果它在getPipelines()内,则只需执行以下操作即可:

return pipelinesService.getPipelines().then(() => {
    should.exist(pipelines);
    pipelines.should.deep.equal({ 
    // more code ....
});