mercredi 5 juin 2019

Angular 7 + jasmine - strange Istanbul coverage issue ( got 97 instead 100%)

I am suffering from a wired issue with jasmine

when I print the coverage using Istanbul, I got 97% percent coverage instaed of 100. one of the lines inside the if statement is marked as red (meaning was not covered), but for sure and even if I debugging it I see the debugger go inside this if section.

how can its possible??

you can see my comment in the code below to see which line is the "uncovergaed"

here is my test.spec

describe('testService', () => {
  let testBed: TestBed;
  let test: TestService;
  let httpClientMock: jasmine.SpyObj<HttpClient>;
  let loggerMock: jasmine.SpyObj<Logger>;


  beforeEach( async() => {
    httpClientMock = jasmine.createSpyObj('httpClient', ['get']);
    loggerMock = jasmine.createSpyObj('Logger', [
      'debug',
      'error',
      'trace',
      'info',
      'build'
    ]);
    loggerMock.build.and.returnValue(loggerMock);
    testBed = await TestBed.configureTestingModule({
      imports: [],
      declarations: [],
      providers: [
        TestService,
        HttpClient,
        { provide: Logger, useValue: loggerMock },
        { provide: HttpClient, useValue: httpClientMock }
      ]
    }).compileComponents();

  });

  beforeEach(() => {
    service = TestBed.get(TestService);
  });

  it('should create', () => {
    expect(service).toBeTruthy();
  });

  describe('TestService', () => {

    const subject$ = new AsyncSubject<any>();

    let incommingTestServerData: ReturnType<
      typeof getTestServerData
    >;
    let expectedTestResult: Test;
    const defaultsTestValue = new Test();

    beforeEach(() => {
      incommingTestServerData = getTestServerData();

      expectedTestResult = plainToClass(Test, incommingTestServerData);
    });

    // this test should pass the validation
    it('should get test from server', async () => {
      httpClientMock.get.and.returnValue(subject$);

      service.loadTets();
      subject$.next(incommingTestServerData);
      subject$.complete();

      const testRes: Test = await new Promise((resolve, reject) => {
        service.get$.subscribe(value => {
          resolve(value);
        });
      });

      expect(defaultsTestValue).toEqual(testRes);
    });

it('should resolve default value on validation error', async () => {
      // given
      httpClientMock.get.and.returnValue(subject$);
      incommingTestServerData.value = '10' as any; // create error in validation

      // when
      service.loadTest();
      subject$.next(incommingTestServerData);
      subject$.complete();

      // then
      const TestRes: Test = await new Promise((resolve, reject) => {
        service.get$.subscribe(value => {
          resolve(value);
        });
      });

      expect(defaultsTestValue).toEqual(TestRes);
    });

here is my service relevant code:

 get$: Observable<Test>;
 private testSubject = new AsyncSubject<Test>()

  constructor(private readonly http: HttpClient, logger: Logger) {
    this.get$ = this.testSubject.asObservable();
  }

  async validation(obj: Test) {
    const validationResult = await validate(obj);
    // this row the coverage is skipped but the debugger not  
    if (validationResult.length > 0) { 
      throw new Error('error');

    } else {
     //do smth without return
    }
  }

  async loadTest() {
    if (this.flag) {
      return;
    }

    this.flag = true;

    try {
      const testRes = await this.http
        .get<Test>(TestService.apiEndpoint)
        .toPromise();
      const obj = plainToClass(Test, testRes as Object);
      await this.validation(obj);

    } catch (e) {
      this.logger.debug(e.message);
      this.logger.debug('could not fetch test');
    } finally {
      this.testSubject.next(this.test);
      this.testSubject.complete();
    }
  }

Aucun commentaire:

Enregistrer un commentaire