Angular - How to unit test an RxJS timer used with AsyncPipe

Discussão em 'Angular' iniciado por reins.ch, Fevereiro 27, 2025.

  1. reins.ch

    reins.ch Guest

    I am unsuccessful in writing a unit test for an RxJS timer that is displayed in the template with an AsyncPipe.

    Component:

    import { Component } from '@angular/core';
    import { AsyncPipe, NgIf } from '@angular/common';
    import { map, timer } from 'rxjs';

    @Component({
    selector: 'app-root',
    template: `
    Timer should fire after {{ delay }} seconds:
    <ng-container *ngIf="timer$ | async as timer; else waiting">Timer fired {{ timer }} times</ng-container>
    <ng-template #waiting>Waiting for Timer…</ng-template>
    `,
    imports: [AsyncPipe, NgIf],
    })
    export class AppComponent {
    delay = 3;
    timer$ = timer(this.delay * 1000, 1000).pipe(map((n) => n + 1));
    }


    Test:

    import { AppComponent } from './main';
    import {
    ComponentFixture,
    TestBed,
    } from '@angular/core/testing';
    import { firstValueFrom } from 'rxjs';

    describe('AppComponent', () => {
    let component: AppComponent;
    let fixture: ComponentFixture<AppComponent>;

    beforeEach(async () => {
    await TestBed.configureTestingModule({
    imports: [AppComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    });

    it('should initially render waiting', () => {
    expect(fixture.nativeElement.textContent).toContain('Waiting'); //passes
    });

    it('should emit timer', async () => {
    expect(await firstValueFrom(component.timer$)).toBe(1); //passes
    });

    it('should show "Timer fired"', () => {
    jest.useFakeTimers();
    jest.advanceTimersByTime(5000);

    expect(fixture.nativeElement.textContent).toContain('Timer fired'); //fails
    });
    });


    Stackblitz: https://stackblitz.com/edit/angular-rxjs-timer-asyncpipe-unit-test?file=src/main.ts,src/test.spec.ts

    The most similar question here on StackOverflow is this one: Angular testing async pipe does not trigger the observable Unfortunately, the solution described in the most upvoted answer does not solve the problem.

    Continue reading...

Compartilhe esta Página