【问题标题】:Jest/Istanbul coverage for a module that isn't loaded with require未加载 require 的模块的 Jest/Istanbul 覆盖率
【发布时间】:2018-09-17 05:43:38
【问题描述】:

foo 模块包含在作为 Node.js 模块加载时无法测试的行:

if (typeof module !== 'object') {
  do.something(); // line shows as uncovered
}
...

这一行不能用require('./foo') 正常测试,因为module 总是真实的,如果不挂接到Node 模块加载器,就不能在模块外模拟。

所以我必须在没有require 的情况下评估它才能完全控制模块局部变量:

const fooSource = fs.readFileSync(fooPath);
new Function('module', fooSource)();
expect(do.something).toHaveBeenCalled();

这可行,但测试覆盖率忽略了此测试。

据我了解,Jest 代码覆盖率(伊斯坦布尔)挂钩到 Node.js 模块加载器并使用覆盖率语句装饰模块主体,例如:

if (typeof module !== 'object') {
  cov_v50bukkd.f[2]++;
  do.something(); // shows as uncovered
}

如何为这条线路启用覆盖?

我不希望仅将 foo 标记为 100% 的覆盖率,而是尽可能使其成为真正的覆盖率,例如手动使用覆盖率语句装饰 fooSource

我的出发点是不应修改foo 源代码以支持代码覆盖率;它在其他方面已经足够可测试了。

【问题讨论】:

    标签: node.js unit-testing code-coverage jestjs istanbul


    【解决方案1】:

    在这种情况下,您可以为您的测试套件显式设置NODE_ENV=testJest 自动设置 NODE_ENV 这样你就可以强制代码覆盖为:

    if (typeof module !== 'object' || process.NODE_ENV === 'test') {
      do.something(); // line shows as uncovered
    }
    

    【讨论】:

    • 谢谢。我想这将是最简单的解决方案,但它不能回答问题。我测试这条线没有问题,只是获得测试覆盖率。此外,应该测试该行并不意味着每次都应该在 Jest 中运行,但这将发生在 NODE_ENV=test 上。正如问题所说,我从不应该修改 foo 源代码以支持代码覆盖率这一事实出发。我想解决问题本身中所述的问题,至少是为了自学。
    • 它实际上回答了您如何报告这种特殊情况的覆盖率。就我而言,Istanbul 之类的覆盖率报告工具用覆盖率语句和辅助函数装饰所有内容,以便静态分析您的代码。我不认为为了支持伊斯坦布尔而装饰你的源代码是一个好主意。顺便看看条件 cmets,它们通常用于指导伊斯坦布尔的装饰器。 github.com/gotwarlost/istanbul#ignoring-code-for-coverage
    • 我看到手动装饰代码的真正问题,但似乎不可能让伊斯坦布尔实例这样做。请考虑使用评论选项更新答案,我想这是最可行的方法,通常可以推荐,似乎用于类似 UMD 包装器的情况。
    猜你喜欢
    • 1970-01-01
    • 2019-03-15
    • 2016-04-12
    • 1970-01-01
    • 2021-11-05
    • 2020-05-05
    • 2016-05-23
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多