unexpected uncovered branch in jest coverage
Asked Answered
A

2

7

I am testing an angular project with jest (using jest-preset-angular).

When collecting coverage, I get an uncovered branch and I don't understand why. I can reproduce the problem with 3 files.

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();
    });
});

by running yarn jest --coverage some-service, I get following coverage:

--------------------|----------|----------|----------|----------|-------------------|
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 |
--------------------|----------|----------|----------|----------|-------------------|

in the HTML report, I get too little information on what is uncovered.

enter image description here

I noticed that removing @Injectable decorator makes the coverage back to 100%

Does someone have an explanation? Is there a way to get my 100% coverage while keeping @Injectable decorator?

Edit: I have added a console.log to prove the constructor is properly invoked. The yellow highlight is given by Istambul report and helps to see the uncovered branch. But there is no branch to me here since there is no condition.

Aylesbury answered 15/8, 2019 at 21:13 Comment(2)
Which version of jest-preset-angular and ts-jest are you using?Splendid
@Splendid I think it was [email protected] and [email protected]Aylesbury
A
5

By comparing with the brand new project created by @markusdresch where coverage is 100% indeed, I finally found that one ts-jest option set in jest.config.js causes side effect on code coverage.

{
    // ...
    globals: {
        'ts-jest': {
            // ...
            isolatedModules: true,
        },
    },
}

isolatedModules set to true causes the uncovered branch described in the original question. By setting it to false or removing it, coverage is back to 100%.

I wish I could use isolatedModules = true and still have a 100% coverage, but I guess this should be a brand new question.

Aylesbury answered 16/8, 2019 at 11:18 Comment(4)
FYI, the reason I want to use isolatedModules is related to this questionAylesbury
Hi @sergio-mazzoleni , have you had any chance to make isolatedModules = true work with 100% coverage? Unfortunately, disabling it in my case generates a huge memory heap because of the size of the project and I don't need type-hinting in testsCarlstrom
@Carlstrom no, sorry, I gave up because I was using isolatedModules: true as a workaround for another problem, but I finally fixed the "root" issue hereAylesbury
I've solved by disabling decorators in my tsconfig.test.json and mocking them. Now I can keep isolatedModules: true. I don't need type-hinting in jest (the build process is enough already) and the performance without it are outstanding.Carlstrom
H
1

I created a brand new Angular app, added jest-preset-angular and the tests you mention, and it's 100% code coverage.

Check out 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 |                   |
---------------------|----------|----------|----------|----------|-------------------|
Heedful answered 16/8, 2019 at 6:24 Comment(9)
Thanks for your answer. Unfortunately, I already tried what you propose and it has no effect on code coverage, still at 75% when using TestBedAylesbury
what if you create a component that consumes the service and test the component?Heedful
Alas, it makes no differenceAylesbury
what does your component.spec look like? does it have a ConfigureFn? i get 100% coverage.Heedful
i added the full procedureHeedful
I appreciate the time and efforts you put in this. However... 1) I still don't get 100% coverage with your proposal; 2) it seems to be a lot of code for a simple branch not covered 3) I don't even understand what is not covered, I mean the service constructor is executed since an instance is properly created 4) create a component to test a service seems odd to me. There should be an easier way :-)Aylesbury
I edited my question. I just like to understand what branch is uncovered...Aylesbury
added example. 100% coverage.Heedful
By comparing your project with mine, I finally discovered that the ts-jest option isolatedModules: true I use in my jest.config.js seems to be the culprit. By removing it, coverage is 100%. I owe you one :-)Aylesbury

© 2022 - 2024 — McMap. All rights reserved.