BehaviorSubject<MediaSuffix>无法赋值给Observable<MediaSuffix>的解决方法
修复Jasmine测试中BehaviorSubject与Observable类型不匹配问题
问题重现
测试代码如下:
const a = jasmine.createSpyObj<AppService>('as', ['getAppsForUserByRoleObservable']); const msMock = jasmine.createSpyObj<MediaService>('ms', ['getMediaSuffix']); const observable = new BehaviorSubject(MediaSuffix.Lg); msMock.getMediaSuffix.and.returnValue(observable);
执行时报错:
Argument of type 'BehaviorSubject
' is not assignable to parameter of type 'Observable '. Type 'BehaviorSubject' is missing the following properties from type 'Observable': _isScalar, _trySubscribe, _subscribe
尝试用rxjs的of操作符无效,需要解决类型匹配问题。
修复方案
1. 利用BehaviorSubject的asObservable()方法
BehaviorSubject自带asObservable()方法,专门用来返回一个纯Observable类型的实例,刚好能解决类型不兼容的问题:
const observable = new BehaviorSubject(MediaSuffix.Lg); msMock.getMediaSuffix.and.returnValue(observable.asObservable());
2. 显式类型断言
如果不想用asObservable(),可以直接通过类型断言告诉TypeScript这个BehaviorSubject就是符合要求的Observable:
const observable = new BehaviorSubject(MediaSuffix.Lg); msMock.getMediaSuffix.and.returnValue(observable as Observable<MediaSuffix>);
3. 检查实际服务的返回类型
如果上面两种方案都没解决,先确认MediaService中getMediaSuffix方法的定义:
- 如果该方法实际返回的是
BehaviorSubject<MediaSuffix>,那应该把mock的返回类型也改成对应的类型,或者修正服务方法的返回类型为Observable<MediaSuffix>(推荐,因为对外暴露Subject类型会破坏封装)。
关于of操作符无效的说明
of(MediaSuffix.Lg)返回的是冷Observable,它不会像BehaviorSubject一样在订阅时立即推送当前值。如果你的组件逻辑依赖于BehaviorSubject的热推送特性,用of就会导致测试逻辑不符合预期。如果只是类型问题,确保你正确导入了of,比如:
import { of } from 'rxjs';
但本质上,这里的核心问题是BehaviorSubject的类型适配,上面的两种方案才是针对性的解决办法。
内容的提问来源于stack exchange,提问作者Neil Harris
相关产品推荐
相关产品推荐

