Javascript单元同步测试Promise.all

我有一个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","upstream": ["GIT"]});

        pipelinestatusstub
            .withArgs("Weekend")
            .returnspromise().resolves({"status": "Passed","upstream": ["GIT"]});

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

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

问题是管道是{}.如果调用pipelinesService.getPipelines();经过一段时间的延迟,它工作正常.

单独测试这些是很好的,因为存根同步解决,我只是找不到强制Promise.all完成后解决方法.

有没有办法强迫这个?或者我可以使用sinon(或其他东西)将其存在?

感谢任何帮助

解决方法

你需要决定你在测试什么.如果你想使用Promise.all测试代码,你需要返回promise – 或者至少是一些承诺,表明操作已经完成.这并不意味着您必须从现有代码返回承诺:您可以将逻辑包装在另一个私有函数“_foo”中,让现有代码使用它,然后从外部测试“foo”而不是原始代码.

如果这是在getPipelines()内部,那么如果你刚刚做了测试,测试就会起作用:

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

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...