如何在不崩溃的情况下模拟来自 Observable 的错误?
How to mock an error from Observable without crashing?
我有模拟服务
export class DataServiceStub {
numbers$ = of([1,2,3,4,5,6]).pipe(
switchMap((data: number[]) => {
if (this._error) {
return throwError(this._error);
}
return of(data);
});
private _error: string;
setError(msg: string) {
this._error = msg;
}
}
我将在使用该服务的组件中测试一个错误案例
it('should show an error message', async(() => {
const errorMessage = `Fetch data error`;
testDataService.setError(errorMessage);
// spyOnProperty(dataStub, 'numbers$').and.returnValue(throwError(errorMessage));
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.error').textContent).toContain(errorMessage);
}));
组件看起来像这样
@Component({
selector: 'app-root',
template: `
<div *ngFor="let num of numbers$ | async">...</div>
<div *ngIf="error$ | async as error" class="error">{{error}}</div>
`
})
export class AppComponent {
numbers$ = this._dataService.numbers$;
error$ = this._dataService.numbers$.pipe(
filter(() => false),
catchError((error: string) => of(error))
);
}
但是错误影响了整个测试过程。
如何避免这样的结果?
我找到了一个解决方案但是它很难看
it('should show an error message', fakeAsync(() => {
const errorMessage = `Fetch data error`;
spyOnProperty(dataStub, 'numbers$').and.returnValue(throwError(errorMessage));
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.error').textContent).toContain(errorMessage);
// Oh my god! it's a super ugly stuff
const _tick = () => {
try {
tick();
} catch (e) {
_tick();
}
};
_tick();
}));
拜托,别打我:)
该解决方案的灵感来自 Async test with fakeAsync()
也许有人可以改进它...
真正的解决方案很简单:我已经捕获所有可能的异常 :)
之后就不需要丑陋的 hack 了。
我有模拟服务
export class DataServiceStub {
numbers$ = of([1,2,3,4,5,6]).pipe(
switchMap((data: number[]) => {
if (this._error) {
return throwError(this._error);
}
return of(data);
});
private _error: string;
setError(msg: string) {
this._error = msg;
}
}
我将在使用该服务的组件中测试一个错误案例
it('should show an error message', async(() => {
const errorMessage = `Fetch data error`;
testDataService.setError(errorMessage);
// spyOnProperty(dataStub, 'numbers$').and.returnValue(throwError(errorMessage));
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.error').textContent).toContain(errorMessage);
}));
组件看起来像这样
@Component({
selector: 'app-root',
template: `
<div *ngFor="let num of numbers$ | async">...</div>
<div *ngIf="error$ | async as error" class="error">{{error}}</div>
`
})
export class AppComponent {
numbers$ = this._dataService.numbers$;
error$ = this._dataService.numbers$.pipe(
filter(() => false),
catchError((error: string) => of(error))
);
}
但是错误影响了整个测试过程。
如何避免这样的结果?
我找到了一个解决方案但是它很难看
it('should show an error message', fakeAsync(() => {
const errorMessage = `Fetch data error`;
spyOnProperty(dataStub, 'numbers$').and.returnValue(throwError(errorMessage));
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('.error').textContent).toContain(errorMessage);
// Oh my god! it's a super ugly stuff
const _tick = () => {
try {
tick();
} catch (e) {
_tick();
}
};
_tick();
}));
拜托,别打我:)
该解决方案的灵感来自 Async test with fakeAsync()
也许有人可以改进它...
真正的解决方案很简单:我已经捕获所有可能的异常 :)
之后就不需要丑陋的 hack 了。