Angular/RxJS 6 - 如何对 next() 触发的指令抛出异常进行单元测试

标签 angular unit-testing jasmine rxjs throw

在迁移到 RxJs6 之前,我的一个单元测试是:

it('should do what I expect, () => {
  expect(() => {
    myComponent.mySubject.next({message: 'invalid'});
  }).toThrow('invalid is not an accepted message');
})

在我的组件中,我订阅了主题并调用了一个可以抛出异常的私有(private)方法。看起来像那样的东西:

export class MyComponent {
  //...
  mySubject = new Subject();
  //...
  ngOnInit(){
    this.mySubject.subscribe(obj => this._doSomething(obj))
  }
  //...
  private _doSomething(obj) {
    if ('invalid' === obj.message) {
      throw new Error('invalid is not an accepted message');
    }
    //...
  }
}

自从我迁移到 RxJs6 之后,这个 UT 就不再工作了(以前它工作过),我不知道如何让它工作。

我阅读了迁移指南,尤其是这一部分:Replacing synchronous error handling ,但它是关于 subscribe(),而不是 next()...

提前致谢

最佳答案

没错。在 RxJS 5 中,当使用 subscribe 订阅时,如果你没有设置任何 error 处理程序,错误就会被重新抛出。这就是为什么您的单元测试之前有效的原因。

但这不是它在 RxJS 6 中的工作方式,因为所有未处理的错误都在 window.onerrorprocess.on('error') 中重新抛出(取决于您的环境)。

您可以做的是使测试异步,然后检查上面的处理程序之一是否被调用:

it('should do what I expect, done => {
  process.once('error', () => done());

  myComponent.mySubject.next({message: 'invalid'});
});

这是 mocha 风格,但我想在 Jasmine 中它会很相似。

实际上,您所拥有的并不是测试可观察链的好方法,因为是否处理错误只是订阅者的事,而不是调用者的事。换句话说,您不应该测试订阅者如何处理发射。

我花了一段时间才找到合适的提交,但请阅读此处的描述 https://github.com/ReactiveX/rxjs/commit/cd9626a4f93cac6f631d5a97dd9c9b2aa8e4b5db (它也在 CHANGELOG.md 中提到)。

关于Angular/RxJS 6 - 如何对 next() 触发的指令抛出异常进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50333608/

相关文章:

javascript - 有没有办法将外部 Javascript 作为 Jasmine 的来源?

Angular + .net Core 3 + Azure 应用服务-仅允许在特定路由上使用 HTTP?

javascript - javascript 包、node 包和 react 包有什么区别?

jquery - 动态改变 CSS 样式高度

unit-testing - 如何在 Jest 中测试从构造函数调用然后调用其他异步函数的 init() 函数

javascript - 用 enzyme react 测试组件 Prop 变化

javascript - 测试 AngularJs + Jasmine 时无法获取指令中的元素

Angular 6 FormArray 和 HTML 循环

java - 生成一个充满任意值的模拟对象

python - 如何在 Python 中测试命令行应用程序?