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();
});
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();
});