如何在 Angular2 测试中模拟 Observable.throw?

How can I mock an Observable.throw in an Angular2 test?

我想测试我的 Angular2 组件中的错误处理,因此想模拟 return 和 Observable.throw('error') 的服务。如何使用 Jasmine 和 Karma 以及 Angular 2 来完成?

你应该 create 一个 observable,然后调用观察者 error。例如

let mockService = {
  error: false,
  data: 'something',
  getData: () => {
    return Observable.create(observer => {
      if (this.error) {
        observer.error(new Error(..))
      } else {
        observer.next(this.data);
      }
      observer.complete();
    })
  }
}

现在对于您的测试,您可以将模拟用于成功案例和错误案例。对于错误情况,只需将 error 属性 设置为 true。在成功的情况下,next 与数据一起被调用。

当你订阅一个observable时,你可以传递三个回调,successerrorcomplete

service.getData().subscribe(
  (data) => {}   // sucess
  (error) => {}  // error
  () => {}       // complete
)

所以有了observer,在调用observer.nextobserver.errorobserver.complete时,就会调用相应的回调。

您可以简单地模拟 Observable 并使用 Observable.throw({status: 404}) 抛出错误对象并测试 observable 的错误块。

const xService = fixture.debugElement.injector.get(SomeService);
const mockCall = spyOn(xService, 'xMethod')
                       .and.returnValue(Observable.throw({status: 404}));

在这里,我在测试中通过模拟 xSerivexMethodObservable.throw({status: 404}) 抛出 http 404 错误。

这是我针对使用 Rxjs 6 的解决方案

let mockService = {
  getData: () => {
    return of({data:'any data'});
  }
}

spyOn(mockService , 'getData').and.callFake(() => {
  return throwError(new Error('Fake error'));
});

RxJS 6 的简化版本:

let mockService = {
  getData: () => {
    return of({data:'any data'});
  }
}

spyOn(mockService , 'getData').and.returnValue(throwError('test error'));