在迁移到 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.onerror
或 process.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/