Модульный тест вообще не охватывает код (Карма)

#angular #karma-jasmine

#angular #karma-jasmine

Вопрос:

У меня есть компонент:

 export class StopwatchComponent implements OnInit {
  hours = '00';
  minutes = '00';
  seconds = '00';
  isPaused = true;
  isStarted = true;
  num = 0;
  @ViewChild('waitBtn', {read: ElementRef}) waitBtn: ElementRef;

  stopTimer() {
    (this.hours = '00'), (this.minutes = '00'), (this.seconds = '00');
    this.num = 0;
    this.timerService.stop();
    this.isStarted = true;
    this.isPaused = true;
    this.timer.unsubscribe();
  }
}
  

И написал несколько тестов для stopTimer() функции, но когда я запускаю тест с покрытием, они вообще не покрывают его и тоже не ломаются
Вот мой код:

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

  it(`should create all parameters`, () => {          //works
    const fixture = TestBed.createComponent(StopwatchComponent);
    const header = fixture.componentInstance;
    expect(header.hours).toEqual('00');
    expect(header.minutes).toEqual('00');
    expect(header.seconds).toEqual('00');
    expect(header.isPaused).toEqual(true);
    expect(header.isStarted).toEqual(true);
    expect(header.num).toEqual(0);
    fixture.debugElement.query(By.css('#waitBtn'));
  });

 it('should call stopTimer', () => {          //don't
    const mockSpyStopTimer = spyOn(component, 'stopTimer');
    fixture.detectChanges();
    component.stopTimer();
    expect(component.hours).toEqual('00');
    expect(component.minutes).toEqual('00');
    expect(component.seconds).toEqual('00');
    expect(component.num).toEqual(0);
    expect(component.isStarted).toBeTruthy();
    expect(component.isPaused).toBeTruthy();
    expect(mockSpyStopTimer).toHaveBeenCalled();
  });
  

Комментарии:

1. Есть ли какая-либо причина, по которой ваш метод фактически не изменяет какие-либо переменные из их существующих значений?

2. Да, у меня есть другие функции в этом компоненте, которые изменяют эти переменные и stopTime() должны возвращать их к умолчанию

Ответ №1:

Причина, по которой он не распространяется, заключается в том, что когда вы spyOn используете метод, вы теряете детали его реализации и просто получаете «API», где вы можете увидеть, был ли он вызван или нет. Чтобы не потерять детали реализации, используйте .and.callThrough() .

 it('should call stopTimer', () => { 
    // now every time stopTimer is called, we have its original implementation details         
    const mockSpyStopTimer = spyOn(component, 'stopTimer').and.callThrough(); // change this line
    fixture.detectChanges();
    component.stopTimer();
    expect(component.hours).toEqual('00');
    expect(component.minutes).toEqual('00');
    expect(component.seconds).toEqual('00');
    expect(component.num).toEqual(0);
    expect(component.isStarted).toBeTruthy();
    expect(component.isPaused).toBeTruthy();
    expect(mockSpyStopTimer).toHaveBeenCalled();
  });