开玩笑报道中意外发现的分支
Posted
技术标签:
【中文标题】开玩笑报道中意外发现的分支【英文标题】:unexpected uncovered branch in jest coverage 【发布时间】:2019-12-22 06:54:41 【问题描述】:我正在用 jest 测试一个 Angular 项目(使用 jest-preset-angular
)。
收集覆盖率时,我得到一个未覆盖的分支,但我不明白为什么。我可以用 3 个文件重现问题。
some-dependency.ts
export class SomeDependency
some-service.ts
import Injectable from '@angular/core';
import SomeDependency from './some-dependency';
@Injectable()
export class SomeService
constructor(private dependency: SomeDependency)
console.log('service created');
some-service.spec
import SomeService from './some-service';
describe('DerivedClass', () =>
it('should create', () =>
expect(new SomeService(null)).toBeTruthy();
);
);
通过运行yarn jest --coverage some-service
,我得到以下报道:
--------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files | 100 | 75 | 100 | 100 | |
some-dependency.ts | 100 | 100 | 100 | 100 | |
some-service.ts | 100 | 75 | 100 | 100 | 6 |
--------------------|----------|----------|----------|----------|-------------------|
在 html 报告中,我得到的关于未发现内容的信息太少。
我注意到删除 @Injectable
装饰器会使覆盖率恢复到 100%
有人解释一下吗?有没有办法在保持 @Injectable
装饰器的同时获得 100% 的覆盖率?
编辑:我添加了一个 console.log 来证明构造函数被正确调用。黄色突出显示由 Istambul 报告提供,有助于查看未覆盖的分支。但是我这里没有分支,因为没有条件。
【问题讨论】:
您使用的是jest-preset-angular
和ts-jest
的哪个版本?
@wtho 我认为是jest-preset-angular@7.1.1
和ts-jest@24.0.0
【参考方案1】:
通过与@markusdresch 创建的覆盖率确实为100% 的全新项目进行比较,我终于发现jest.config.js
中设置的一个ts-jest
选项会对代码覆盖率产生副作用。
// ...
globals:
'ts-jest':
// ...
isolatedModules: true,
,
,
isolatedModules
设置为 true 会导致原始问题中描述的未覆盖分支。通过将其设置为 false 或将其删除,覆盖率将恢复到 100%。
我希望我可以使用 isolatedModules = true
并且仍然有 100% 的覆盖率,但我想这应该是一个全新的问题。
【讨论】:
仅供参考,我想使用isolatedModules
的原因与这个question有关
嗨@sergio-mazzoleni,你有没有机会让isolatedModules = true 以100% 的覆盖率工作?不幸的是,由于项目的大小,在我的情况下禁用它会产生巨大的内存堆,我不需要在测试中进行类型提示
@Joseph 不,抱歉,我放弃了,因为我使用isolatedModules: true
作为另一个问题的解决方法,但我最终修复了“root”问题here
我已经通过禁用 tsconfig.test.json 中的装饰器并模拟它们来解决。现在我可以保留isolatedModules: true
。我不需要开玩笑的类型提示(构建过程已经足够了)并且没有它的性能非常出色。【参考方案2】:
我创建了一个全新的 Angular 应用,添加了 jest-preset-angular 和您提到的测试,它的代码覆盖率为 100%。
查看https://github.com/markusdresch/angular-jest-example
---------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---------------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
app | 100 | 100 | 100 | 100 | |
app.component.html | 100 | 100 | 100 | 100 | |
app.component.ts | 100 | 100 | 100 | 100 | |
models | 100 | 100 | 100 | 100 | |
some-dependency.ts | 100 | 100 | 100 | 100 | |
services | 100 | 100 | 100 | 100 | |
some.service.ts | 100 | 100 | 100 | 100 | |
---------------------|----------|----------|----------|----------|-------------------|
【讨论】:
感谢您的回答。不幸的是,我已经尝试过您的建议,它对代码覆盖率没有影响,使用 TestBed 时仍为 75% 如果创建一个使用服务的组件并测试该组件会怎样? 唉,没区别 添加了示例。 100% 覆盖率。 通过比较你的项目和我的项目,我终于发现我在my jest.config.js
中使用的ts-jest
选项isolatedModules: true
似乎是罪魁祸首。通过删除它,覆盖率为 100%。我欠你一个:-)以上是关于开玩笑报道中意外发现的分支的主要内容,如果未能解决你的问题,请参考以下文章
应急响应--记录一次漏洞紧急处理中意外发现的挖矿木马(Shiro反序列化漏洞和ddg挖矿木马)