使用 Q Promise 的 node.js 项目的代码覆盖率

Posted

技术标签:

【中文标题】使用 Q Promise 的 node.js 项目的代码覆盖率【英文标题】:Code coverage for node.js project using Q promises 【发布时间】:2014-07-07 03:20:59 【问题描述】:

我目前正在开发一个 node.js 项目。我们将 Q 库用于 Promise (https://github.com/kriskowal/q)。

我们使用 mocha 进行测试,并使用 grunt 任务 (https://github.com/pghalliday/grunt-mocha-test) 提供的代码覆盖,该任务使用毯子.js 进行覆盖,使用 travis-cov 报告器来断言覆盖阈值。

不幸的是,该解决方案没有为承诺提供分支覆盖。

我尝试过 Intern (http://theintern.io/),但是我编写的基本示例也没有显示正确的分支覆盖率。

您能否推荐一个解决方案,该解决方案可以为 Q Promise 提供正确的覆盖范围并与 grunt 和 node 无缝协作?

【问题讨论】:

投票结束,因为这是一个工具请求。不过我对答案很感兴趣。 自那以后有什么进展吗? 嗨,本杰明,我们决定暂时保持解决方案不变,我在这个方向上没有做太多研究。 【参考方案1】:

嗯,检查 promise 的覆盖率应该不会太难,因为 javascript 具有绝对病态面向方面的编程能力。虽然自动化工具在这里是题外话,但让我们来看看 Promise 有哪些分支:

首先,promise 的解析器函数(promise 构造函数或 deferred)有自己的分支。 每个.then 子句有 3 个分支(一个代表成功,一个代表失败,一个代表进度),如果您也想要循环覆盖,您希望每个进度事件在附加进度时触发零次,一次和多次 - 尽管让我们避免在这个问题上取得进展,而且总的来说,因为它在 Q 中已被弃用和替换。 .done.catch等……都是.then的私人案例。像.all 这样的聚合方法是promise 构造函数的私有情况,因为它们创建了一个新的聚合promise,并且它们的.then 也需要检查。

所以,让我们先看看我们如何做到这一点 - 请注意 Q 在内部使用 Promise.prototype.then 作为聚合方法,因此我们可以覆盖它:

Promise.prototype._then = Promise.prototype.then;
var branches = 0;
Promise.prototype.then = function(fulfilled,rejected,progressed)
    branches += (fulfilled.call) +(rejected.call) + (progressed.call);
    var nFulfilled = function() branches--;return fulfilled.apply(this,arguments); ;
    var nRejected = function() branches--; return rejected.apply(this,arguments); ;
    //progression may happen more than once
    var nProgressed = function() 
        if(!nProgress.happened) 
            branches--;
            nProgress.happened = true;
        
        return progressed.apply(this,arguments); 
    ;
    nProgressed.happened = false;
    return this._then((fulfilled.call) ? nFulfilled : undefined,
                      (rejected.call) ? nRejected : undefined,
                      (progressed.call) ? nProgressed : undefined);
;

我们在这里所做的是挂钩每个 .then 并跟踪附加的处理程序和被调用的处理程序。

branches 变量将包含使用 Promise 创建但未实际执行的代码路径的数量。您可以在这里使用更复杂的逻辑(例如 - 计数而不是减去),我希望看到有人拿起手套并从中制作一个 git repo :)

【讨论】:

通过var Promise = Q.makePromise访问promise对象。

以上是关于使用 Q Promise 的 node.js 项目的代码覆盖率的主要内容,如果未能解决你的问题,请参考以下文章

如何在 node.js 中实际使用 Q Promise?

Promise 与 q 框架和 Node.js 中的回调模式?

Node.js 异步库比较 - Q 与 Async

Node js,使用带有Q promise的mongoose不会调用reject函数

node.js 模块:Async vs Fibers.promise vs Q_oper8

promise之nodejsQ的详细用法总结