Search code examples
angularunit-testingrxjsngrx

Testing OnDestroy component observable


I have a component, which calls on some observables and listens to them, and cleans the subscriptions (advances and closes them) on destroy, but I can't seem to get the test working properly. Am I running the test wrong? The component does clean up its observables.

Component

export class DevicesComponent implements OnDestroy {
   public completer$: Subject<void> = new Subject<void>();

   this.deviceFacade.dataLoaded$.pipe(takeUntil(this.completer$)).subscribe({
            next: (loading: boolean) => {
                if (!loading) {
                    this.spinner.show();
                } else {
                    this.spinner.hide();
                }
            },
            error: (err: string | null) => console.log(err),
        });

    ngOnDestroy(): void {
        this.completer$.next();
        this.completer$.complete();
    }
}

Test

    it('should call method and unsubscribe on destroy', () => {
        const destroy = spyOn(component, 'ngOnDestroy');
        const next = spyOn(component.completer$, 'next');
        const complete = spyOn(component.completer$, 'complete');

        component.ngOnDestroy();
        fixture.detectChanges();

        expect(destroy).toHaveBeenCalled();
        expect(next).toHaveBeenCalled();
        expect(complete).toHaveBeenCalled();
    });

Solution

  • spyOn doesn't invoke the actual implementation by default. You can enable it with and.callThrough()

        it('should call method and unsubscribe on destroy', () => {
            const destroy = spyOn(component, 'ngOnDestroy').and.callThrough();
            const next = spyOn(component.completer$, 'next');
            const complete = spyOn(component.completer$, 'complete');
    
            component.ngOnDestroy();
            fixture.detectChanges();
    
            expect(destroy).toHaveBeenCalled();
            expect(next).toHaveBeenCalled();
            expect(complete).toHaveBeenCalled();
        });
    

    https://scriptverse.academy/tutorials/jasmine-spyon.html