angular - 在服务中使用 observables 测试错误案例

标签 angular typescript karma-coverage angular2-testing angular2-observables

假设我有一个订阅服务功能的组件:

export class Component {

   ...

    ngOnInit() {
        this.service.doStuff().subscribe(
            (data: IData) => {
              doThings(data);
            },
            (error: Error) => console.error(error)
        );
    };
};

订阅调用采用两个匿名函数作为参数,我已经设法为数据函数设置了一个工作单元测试,但 Karma 不会接受错误函数的覆盖。

enter image description here

我试过监视 console.error 函数,抛出一个错误,然后期望 spy 被调用,但并没有完全做到。

我的单元测试:

spyOn(console,'error').and.callThrough();

serviceStub = {
        doStuff: jasmine.createSpy('doStuff').and.returnValue(Observable.of(data)),
    };

    serviceStub.doStuff.and.returnValue(Observable.throw(

        'error!'
    ));

serviceStub.doStuff().subscribe(

    (res) => {

        *working test, can access res*
    },
    (error) => {

      console.error(error);
      console.log(error);  //Prints 'error!' so throw works.
      expect(console.error).toHaveBeenCalledWith('error!'); //Is true but won't be accepted for coverage.
    }
);

测试此类匿名函数的最佳实践是什么?确保测试覆盖率的最低限度是多少?

最佳答案

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

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

2019 年更新:

既然有些人懒得看评论让我把这个放在这里: 为 Rxjs 使用错误是最佳实践

import { throwError } from 'rxjs'; // make sure to import the throwError from rxjs
const xService = fixture.debugElement.injector.get(SomeService);
const mockCall = spyOn(xService,'method').and.returnValue(throwError({status: 404}));

2022 年更新: 以上述方式使用 throwError 已被弃用。相反,使用 throwError(() => new Error({status: 404})):

import { throwError } from 'rxjs'; // make sure to import the throwError from rxjs
const xService = fixture.debugElement.injector.get(SomeService);
const mockCall = spyOn(xService,'method').and.returnValue(throwError(() => new Error({status: 404})));

关于angular - 在服务中使用 observables 测试错误案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39960146/

相关文章:

Angular 2 - 如何访问指令并在其中调用成员函数

Angular 6 升级 : debounceTime is not property of Subject

javascript - 使用 Istanbul + Webpack 对 JSX 文件进行代码覆盖

angularjs - 使用 Karma Jasmine 进行 Angular 1.5 组件模板单元测试

Angular6 将数据传递给 ng-template

javascript - 我只想选择当前页面的所有记录

Angular 2 ngModel 无法绑定(bind)表达式?

javascript - 有没有办法在 typescript 中使用上下文绑定(bind)

typescript - Vue 2.5 vue-class-component 使用 Vue 命名空间,但它是一个类型

Angular 6 代码覆盖率......如何在应用程序的代码覆盖率中排除本地库?