How do I unit test if http request has been canceled using HttpTestingClientModule?

239 views Asked by At

My component is invoking the method to get data from the server, it happens in ngOnInit lifecycle of the component. The request takes some time, and the user can navigate away from current view and destroy the component. In such a case, the get data request should be canceled. And this is what happens in actual application.

Image of cancelled request in network tab

Now my goal is to unit test this behavior. What approach should I take? My current implementation is pretty naive and doesn't work...

What should I do in order to simulate request cancellation?

Here's my approach:

Component class:

@Component({
    ...
    providers: [ProjectsOverviewService] <-- Lifecycle of service depends on component
    ...
})
export class ProjectsOverviewComponent implements OnInit {
    constructor(private projectsOverviewService: ProjectsOverviewService) {}

    ngOnInit() {
        this.projectsOverviewService.getSomeData();
    }
}

Service class:

@Injectable()
export class ProjectsOverviewService implements OnDestroy {
    private someData: Data;
    private serviceDestroyed$ = new Subject();

    constructor(private projectPageService: ProjectPageService) {}

    ngOnDestroy() {
        this.serviceDestroyed$.next();
    }

    getSomeData() {
        this.projectPageService.projectsGetAll$
        .pipe(takeUntil(this.serviceDestroyed$))
        .subscribe(data => this.someData = data);
    }
}

Spec file:

let component: ProjectsOverviewComponent;
let fixture: ComponentFixture<ProjectsOverviewComponent>;
let httpTestingController: HttpTestingController;

beforeEach(async () => {
    await TestBed.configureTestingModule({
        imports: [
            HttpClientTestingModule
        ],
        declarations: [ProjectsOverviewComponent],
        providers: [ProjectsServiceProxy]
    }).compileComponents();
});

beforeEach(() => {
    fixture = TestBed.createComponent(ProjectsOverviewComponent);
    component = fixture.componentInstance;
    httpTestingController = TestBed.inject(HttpTestingController);
    fixture.detectChanges();
});

it('should cancel get some data request when component is destroyed', () => {
    const req = httpTestingController.expectOne('/api/services/app/Projects/GetAll');

    console.log(req); // TestRequest

    component.ngOnDestroy();

    expect(req.cancelled).toBe(true); // Fails - expected false, to be true.
});
0

There are 0 answers