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



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

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

在我的组件中,我订阅了主题并调用了一个可以引发异常的私有方法。看起来像这样的东西:

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 不再工作(它以前工作过(,我不知道如何让它工作。

我阅读了迁移指南,尤其是本节:替换同步错误处理,但它是关于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风格,但我想在茉莉花中它会很相似。

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

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

我找到了解决方法。

不确定相关性,但它似乎对我有用。

我使用角度测试方法fakeAsynctick来触发未处理异常的发射。

变换:

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

到:

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

顺便说一句,这个技巧也让我确信,如果不抛出异常,测试就会失败。

最新更新