升级Angular/rxjs 6后Karma测试失败问题求助
Angular升级后Karma测试中RxJS Observable比较失败的问题解决
问题背景
升级Angular版本后,原本正常运行的Karma测试用例突然失效,问题出在针对错误处理函数handleError的测试上。先看下相关代码:
错误处理函数:
import { Observable, of } from 'rxjs'; export function handleError<T>(operation='operation', result?: T) { return (error: any): Observable<T> => { console.error(error); console.info(`${operation} failed: ${error.message}`); return of(result as T); } }
测试代码中这一行断言失败:
expect(errorFunction({ message: 'Something went wrong.'})).toEqual(of([{}]));
报错信息:Expected $._subscribe = Function to equal Function.
原因分析
你猜测异步是问题根源其实不准确,核心矛盾在于不能直接用toEqual比较两个独立的RxJS Observable实例。
每调用一次of()都会生成一个全新的Observable对象——哪怕它们要发射的值完全一致,这些Observable的内部属性(比如_subscribe函数)都是独立的引用。Jasmine的toEqual会做深度对象检查,当发现这些内部函数引用不同时,就会判定两个对象不相等,这就是报错的直接原因。
可能旧版本的RxJS/Angular内部实现让这种不规范的比较碰巧能通过,但升级后内部逻辑变化,这个原本就存在的测试写法问题就暴露出来了。
正确的解决方案
我们要验证的是Observable最终发射的值,而非Observable实例本身,所以正确的做法是订阅这个Observable,在回调中对发射的值做断言:
it('#handleError return function should return an object and emit correct value', () => { let errorFunction = handleError('dummyFetch', [{}]); expect(typeof errorFunction({ message: 'Something went wrong.' })).toEqual('object'); let errorObservable = errorFunction({ message: 'Something went wrong.' }); errorObservable.subscribe(value => { expect(value).toEqual([{}]); }); });
如果想更严谨地处理异步测试,还可以用Jasmine的done回调确保断言执行完成:
it('#handleError return function should emit correct value', (done) => { let errorFunction = handleError('dummyFetch', [{}]); let errorObservable = errorFunction({ message: 'Something went wrong.' }); errorObservable.subscribe(value => { expect(value).toEqual([{}]); done(); // 通知Jasmine异步操作已完成 }); });
另外,针对更复杂的Observable流测试,推荐使用RxJS的marble测试方式,能更清晰地验证异步流的完整行为。
内容的提问来源于stack exchange,提问作者Gitnik
相关产品推荐
相关产品推荐

