Monday, 1 February 2021

Angular 11 Testing with Jest - Aync error with rxjs timer

I am having the following error while writing a test: "Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout."

This is the test:

beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [DashboardTimerComponent, FormatTimePipe],
        imports: [BrowserAnimationsModule, ReactiveFormsModule],
        providers: [FormBuilder],
      }).compileComponents();
    }),
  );

  beforeEach(() => {
    fixture = TestBed.createComponent(DashboardTimerComponent);
    component = fixture.componentInstance;
  });

  it('should stop counter and emit event', fakeAsync(() => {
    spyOn(component.stopped, 'emit');

    component.stopRequested = true;
    component.runningTimer = { timer: 19 };
    fixture.detectChanges();
    

    const button = fixture.debugElement.nativeElement.querySelector('#stop');
    button.click();

    expect(component.timer).toBeNull();
    expect(component.stopped.emit).toHaveBeenCalled();
  }));

This is the component:

@Component({
  selector: 'dashboard-timer',
  templateUrl: './dashboard-timer.component.html',
  providers: [DashboardTimerService],
  animations: [fadeInAnimation],
})
export class DashboardTimerComponent {
  @Input() projects: any;
  @Input() runningTimer: any = null;

  @Output() started = new EventEmitter();
  @Output() stopped = new EventEmitter();

  public form: FormGroup;

  public timer: number = null;

  public stopRequested: boolean = false;

  public counter: Subscription;

  private project: FormControl = new FormControl('');

  private note: FormControl = new FormControl('');

  constructor(
    private dashboardTimerService: DashboardTimerService,
    private fb: FormBuilder,
  ) {}

  ngOnInit() {
    // initialize form
    this.form = this.fb.group({
      project: this.project,
      note: this.note,
    });

    if (this.runningTimer) {
      this.timer = this.runningTimer.timer;
      this.form.controls['project'].setValue(this.runningTimer.project || '');
      this.form.controls['note'].setValue(this.runningTimer.note || '');

      this.counter = this.dashboardTimerService
        .getCounter()
        .subscribe(() => this.timer++);
    }
  }

  /**
   * check if stop requested, stop counter, emit stop to parent component
   */
  stop(): void {
    if (this.stopRequested === false) {
      this.stopRequested = true;

      setTimeout(() => {
        this.stopRequested = false;
      }, 5000);
      return;
    }
    this.stopRequested = false;

    this.counter.unsubscribe();
    this.stopped.emit();
    this.timer = null;
  }
}

The error seems to be resulting from this service:

import { Injectable } from '@angular/core';
import { timer } from 'rxjs';

@Injectable()
export class DashboardTimerService {
  getCounter() {
    return timer(0, 1000);
  }
}

I suppose the timer is still running, even though I unsubscribe from it in the component.

Any ideas how to solve this are very much appreciated!

Thank you!



from Angular 11 Testing with Jest - Aync error with rxjs timer

No comments:

Post a Comment