使用Jest测试Angular中Subscription.unsubscribe调用出现报错如何解决?
问题原因及正确实现
错误原因
- 你在
expect断言中主动调用了unSubscribe(),首先存在拼写错误,RxJS的Subscription实例取消订阅的方法名是全小写的unsubscribe;其次加括号执行方法后返回的是执行结果,不是你用jest.spyOn创建的监听函数本身,因此Jest抛出「收到的值必须是mock或spy函数」的报错。 - 你贴出的组件代码存在手误:
@Component装饰器首字母要大写,ngOnDestroy需要实现OnDestroy生命周期接口,实际项目中要注意修正语法问题。
正确实现方式
方案1:基于原有代码调整
只需要修正断言逻辑,直接对spy实例做断言即可:
it('should unsubscribe when ngOnDestroy is called', () => { component.dataSubscription = new Subscription(); // 存储创建的spy实例 const unsubscribeSpy = jest.spyOn(component.dataSubscription, 'unsubscribe'); component.ngOnDestroy(); // 直接断言spy的调用次数,不要执行方法 expect(unsubscribeSpy).toHaveBeenCalledTimes(1); // 也可以直接写 expect(component.dataSubscription.unsubscribe).toHaveBeenCalledTimes(1) });
方案2:更轻量的Mock实现(推荐)
不需要实例化真实的Subscription,直接创建带Mock方法的对象即可,测试执行效率更高:
it('should unsubscribe when ngOnDestroy is called', () => { // 直接构造带mock取消订阅方法的对象 component.dataSubscription = { unsubscribe: jest.fn() } as Subscription; component.ngOnDestroy(); expect(component.dataSubscription.unsubscribe).toHaveBeenCalledTimes(1); });
内容的提问来源于stack exchange,提问作者Elvis Shrestha
相关产品推荐
相关产品推荐

