I'm trying to unit test a small part of the Modal component, but I'm having hard times working with observables. My main problems are http requests that are not invoked one after another when I run code in Karma and Jasmine (I guess Angular TestBed is involved too).
What happens in real browser for the application is pretty simple: Click on button to show modal, fetch data (2 requests, one after another) and visualize it to the user. Works as expected, but as soon as I try to test it, the second http request is not sent.
Here's part of the code I wrote with comments:
export class CreateOrEditProjectModalComponent {
private subs = new Subscription();
private plan: Plan;
constructor(private httpService: HttpService, private formService: FormService) {}
show(id: string) {
this.getModalData$(id).subscribe({
complete: () => {
// some action here
}
})
}
private getModalData$(projectId: string): Observable<void> {
return this.getProject$(projectId).pipe(
switchMap(({ project }) => {
console.log(project); <- all good, received mocked project;
this.formService.assignFormFields(project);
console.log(this.formSerice.nameControl.value); <- all good, has value from mocked project;
return this.getPlan$(project.planId);
}),
switchMap((plan) => {
console.log(plan); <- problem, not reaching here;
this.plan = plan;
return EMPTY;
})
);
}
private getProject$(id: string): Observable<Project> {
return this.httpService.getProject(id);
}
private getPlan$(id: string): Observable<Plan> {
return this.httpService.getPlan(id);
}
}
it('should get project and plan data after showing the modal', () => {
component.show('123456');
const projectReq = httpTestingController.matchOne('/api/project/123456');
projectReq.flush(mockedProject); <- all good until this point;
expect(component.formService.nameControl.value).toBe(mockedProject.name); <- This one is not working too. I expect that after flushing, it will go through the code specified in component.ts file (will assign project values to formService reactive form controls)
const planReq = httpTestingController.matchOne('/api/plan/1');
// Test runner fails here: Expected one matching request for criteria "Match URL: app/plan/1", found none.
planReq.flush(mockedPlan);
}
I have no clue how I can reach to the second observable or why the values in formService
are not available after first flush()