I have method like this in my application:
public async onImport(importedCalculations: ImportCalculation, btn: HTMLButtonElement): Promise<void> {
try {
this.renderer.addClass(btn, 'loading');
const response: any = await this.ics.import(importedCalculations.id);
of(true).pipe(
mergeMap(() => Observable.from(this.ics.getProcessQueue(response.id))),
map((response: any) => {
if (response.state !== QueueState.READY) {
throw new Error('File is not ready');
}
return { ...response }
}),
retryWhen(genericRetryStrategy()),
catchError(error => of(error))
).subscribe((response: ProcessQueue) => {
this.refreshCollection({
...importedCalculations,
imported: true
});
if (response.message) {
this.modalService.open(new LogsModal(response.message.split('<br>')))
}
this.renderer.removeClass(btn, 'loading');
});
} catch (e) {
console.log(e);
this.renderer.removeClass(btn, 'loading');
if (e instanceof HttpErrorResponse) {
if (e.status == 403) {
this.mgs.set403();
}
else {
this.mgs.set(`Wystąpił problem podczas przygotowywania pliku.`);
}
}
}
}
I want to unit test this using jasmine, such that the http request first returns an error but on a subsequent try, returns the expected data.
I try do this in this way:
it('shoud...', async(() => {
const spy = spyOn(ics, 'import').and.returnValue(Promise.resolve({ id: 1 }))
spyOn(component, 'onImport').and.callThrough();
spyOn(ics, 'getProcessQueue');
component.importedCalculations = { items: mockCalculationImportData, total: 1 } as ApiResponse<ImportCalculation>;
fixture.detectChanges();
const button = debugElement.query(By.css('.reset')).nativeElement
component.onImport(mockCalculationImportData[0], button);
expect(button.classList).toContain('loading')
spy.calls.mostRecent().returnValue.then(() => {
expect(ics.reset).toHaveBeenCalledWith(mockCalculationImportData[0].id);
})
}))
and it works... but I want to test rest of code, and when i add
expect(ics.getProcessQueue).toHaveBeenCalledTimes(4)
in promise resolver test failed with error:
Expected spy getProcessQueue to have been called 4 times. It was called 1 times.
This is my mockup service:
const importCalculationsServiceStub = {
state: 0,
post() {
return fakeAsyncResponse([{ id: 1 }]);
},
cget() {
return fakeAsyncResponse({ items: mockCalculationImportData, total: 1 })
},
reset() {
return fakeAsyncResponse([{ id: 1 }]);
},
get() {
return fakeAsyncResponse({ url: 'test' })
},
open() {
return fakeAsyncResponse({ url: 'test' })
},
getProcessQueue(id) {
this.state++;
if (this.state > 3) {
return fakeAsyncResponse({ state: QueueState.READY })
}
return fakeAsyncResponse({ state: QueueState.PICKED_UP })
}
};
Is there any possibility of achieving this and do this in the right way?