【发布时间】:2016-11-24 01:43:41
【问题描述】:
我有一个 node.js 应用程序,其中有一个维护状态的对象和一个每 30 秒更新一次状态的更新循环。基本上,它是一个构建监视器,在向前端提供每个管道的最新状态时查询构建机器。
在更新循环中,我需要进行多次调用,为此我需要所有数据才能从中获得任何有用的信息。目前我将所有这些调用包装在一个 Promise 中并使用 Promise.all 等待它们全部完成。
在测试中,我使用 sinon-stub-promise 包同步解析每个 Promise。这对于单个承诺非常有效。然而问题是它不适用于 Promise.all - 至少是同步的。如果我在测试中设置了一个小超时,那么它就可以通过了。
这里有一些sn-ps:
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 的列表,然后创建一个请求,该请求为每个管道返回一个承诺。这在我手动测试时有效。
现在是测试代码:
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(或其他东西)来消除它吗?
感谢任何帮助
【问题讨论】:
-
你必须在上面的 sn-p 中返回 Promise.all 的结果。在下面的测试中,返回 Promise 并链接一个
then块,您将在其中返回从 Promise 返回的值。 -
不,没有办法做到这一点。 Promise 是异步的。要测试涉及它们的任何内容,请编写异步测试。
-
我不确定我是否遇到了您的问题,您是否遇到了测试本身的问题?如果是这样,有一个参数叫做 done,所以你可以得到它并在 promise.all 回调中调用它,看:semaphoreci.com/community/tutorials/… at "Async Tests with sinon.test"
-
我试图避免在任意超时的情况下进行异步操作,因为似乎应该有更好的方法。我宁愿不返回 promise.all,因为它不是该方法的真正用途,它用于根据返回请求的值更新状态。
-
要运行异步测试,您需要知道异步任务何时完成。如果没有返回 promise 或没有调用 'done' 回调,mocha 会在几秒后自动触发超时。
标签: javascript node.js unit-testing promise sinon