事件回调的代码覆盖率

min*_*gos 10 javascript code-coverage callback karma-runner istanbul

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

我试图测试的代码大致如下:

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

    element.addEventListener("input", callback);
};
Run Code Online (Sandbox Code Playgroud)

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

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

element.addEventListener("input", function() {
    callback();
});
Run Code Online (Sandbox Code Playgroud)

但是,我完全鄙视修改应用程序代码的"解决方案",以弥补代码质量控制工具的不足.

有没有一种方法可以让代码覆盖得到正确的选择而无需在匿名函数中包装回调?

Jas*_*lin 0

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

// 编辑示例

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

var foo = function (callback) {
    // do stuff
    callback(arguments);
}
Run Code Online (Sandbox Code Playgroud)

现在为 foo 的功能创建一个测试,并为callback的功能创建一个单独的单元测试。单元测试应该只测试一件事。每个函数都应该有自己的单元测试。测试foo执行它应该执行的操作(无论回调如何),并且该回调执行它应该执行的操作(传入您自己的模拟数据进行测试)。一般来说,命名函数始终是最佳选择。