11

我使用 Karma(当前为 v0.10.10)和 Jasmine 进行单元测试,并使用 Istanbul(通过 karma-coverage)进行代码覆盖率报告。我注意到代码覆盖率报告器在特定情况下的奇怪行为。

我要测试的代码大致是这样的:

/**
 * @param {HTMLInputElement} element
 */
var foo = function(element) {
    var callback = function() {
        // some code
    };

    element.addEventListener("input", callback);
};

在我的测试中,我在被测元素上调度了一个自定义输入事件,并且回调函数执行。测试检查回调的效果,测试通过。事实上,即使我console.log("foo")在回调中放了一个毛茸茸的东西,我也可以清楚地看到它被打印出来了。但是,Istanbul 的报告错误地表明回调根本没有执行

修改测试代码以在事件侦听器的回调中使用匿名函数可修复错误行为:

element.addEventListener("input", function() {
    callback();
});

但是,我完全鄙视修改应用程序代码以弥补代码质量控制工具缺陷的“解决方案”。

有没有一种方法可以在不将回调包装在匿名函数中的情况下正确获取代码覆盖率?

4

2 回答 2

0

我的nodejs代码的部分回调没有被标记为已覆盖,即使我的测试确实覆盖了它们,我也遇到了这个确切的问题。我在 mocha/istanbul 和 mocha/blanket.js 都遇到了这个问题。

我最终注意到我的许多测试都没有运行代码覆盖率,这导致了我的问题。

我通过--recursive向 mocha 添加选项来解决它,因为某些测试位于子目录中。

于 2016-02-25T15:04:23.983 回答
0

回调正在传递到您的方法中。除了您的函数定义之外,Istanbul 完全不知道该回调来自何处。Istanbul 知道 callback() 来自 parameter callback,但不知道该回调的内部(例如,在作为回调传入之前的函数)。

// 编辑示例

var callback = function(args) {
    //do stuff
}

var foo = function (callback) {
    // do stuff
    callback(arguments);
}

现在为 foo 的功能创建一个测试,并为 foo 的功能创建一个单独的单元测试callback。单元测试应该只测试一件事。每个函数都应该有自己的单元测试。测试foo做它应该做的事情(不管回调),并且那个回调做它应该做的事情,(传递你自己的模拟数据进行测试)。一般来说,命名函数总是要走的路。

于 2016-01-28T21:41:51.550 回答