I'm using [email protected], [email protected], [email protected]
I'm trying to test my Angular component unhappy ngOnInit behavior mapping a promise to an observable, i.e. the catchError block:
ngOnInit() {
this.initializeEditConcernFormGroup$ = from(this.concernService.getConcernById(this.currentConcernId)).pipe(
tap(() => (this.loadingError = null)),
switchMap((receivedConcern) => this.handleReceivedConcern(receivedConcern)),
map(({ concern, concernConfiguration }) => this.concernFormService.createConcernFormGroup(concernConfiguration.concerns, concern)),
tap((formGroup) => (this.editConcernFormGroup = formGroup)),
catchError( err => {
this.loadingError = err;
return EMPTY;
}));
}
In my test I'm overriding the service method with a mock implementation that rejects a promise:
it('should set loadingError if getConcernById fails', fakeAsync(() => {
const errorMessage = 'Oops!...';
concernService.getConcernById = jasmine.createSpy().and.callFake(() => Promise.reject(errorMessage));
component.ngOnInit();
tick(100); // promise reject being raised here
expect(component.loadingError).toEqual(errorMessage);
}));
Unfortunately on tick(100) the test fails with the following stack trace:
Error: Uncaught (in promise): Error: Oops!...
Error: Oops!...
at ConcernServiceMock.<anonymous> (src/app/administration/pages/concern/edit-concern/edit-concern.component.spec.ts:184:98)
at SpyStrategy.exec (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:9326:39)
at SpyStrategyDispatcher.exec (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8845:23)
at spy (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8725:46)
at node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8698:16
at ConcernServiceMock.wrap [as getConcernById] (node_modules/jasmine-core/lib/jasmine-core/jasmine.js:8771:20)
at EditConcernComponent.ngOnInit (src/app/administration/pages/concern/edit-concern/edit-concern.component.ts:125:76)
at UserContext.<anonymous> (src/app/administration/pages/concern/edit-concern/edit-concern.component.spec.ts:185:21)
at UserContext.fakeAsyncFn (node_modules/zone.js/fesm2015/zone-testing.js:2032:1)
at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:372:1)
at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:287:1)
at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:371:1)
at Zone.run (node_modules/zone.js/fesm2015/zone.js:134:1)
at runInTestZone (node_modules/zone.js/fesm2015/zone-testing.js:582:1)
catchError is never being executed. It seems from from RxJS cannot deal with rejected Promises. The error bubbles up and then it hits the test execution which finally fails the test. No expect is being executed.
As far as I analysed it, it does not seem the be a zone.js issue. At least
Zone[Zone.__symbol__['ignoreConsoleErrorUncaughtError']] = true;
didn't help.
What am I doing wrong here? Any help appreciated.