我使用Karma(目前为v.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")
,我也可以清楚地看到它被打印出来。但是,伊斯坦布尔的报告错误地表明回调未执行。
修改测试代码以在事件监听器的回调中使用匿名函数修复了错误行为:
element.addEventListener("input", function() {
callback();
});
然而,我完全鄙视"解决方案"修改应用程序的代码以补偿代码质量控制工具的不足。
有没有办法让代码覆盖率得到正确的选择,而无需在匿名函数中包装回调?
答案 0 :(得分:0)
回调正在传递给您的方法。除了函数定义之外,伊斯坦布尔完全不知道回调的来源。伊斯坦布尔知道callback()来自参数callback
,但不知道该回调的内部(例如,它作为回调传入之前的函数)。
//编辑示例
var callback = function(args) {
//do stuff
}
var foo = function (callback) {
// do stuff
callback(arguments);
}
现在为foo的功能创建测试,并为callback
的功能单独进行单元测试。单元测试应该只测试一件事。每个功能都应该有它自己的单元测试。测试foo
做了它应该做的事情(不管回调)和回调是做了它应该做的事情,(传递你自己的模拟数据进行测试)。通常,命名函数总是可行的。
答案 1 :(得分:0)
我有一个确切的问题,我的nodejs部分代码中的回调没有标记为覆盖,即使我有测试肯定覆盖了它们。我有mocha / istanbul和mocha / blanket.js这个问题。
我最终注意到我的许多测试都没有运行代码覆盖率,这导致了我的问题。
我通过向mocha添加--recursive
选项解决了这个问题,因为有些测试在子目录中。