Angular单元测试中mock Observable后subscribe内代码未执行如何解决
问题根源
你在测试中 mock 服务方法返回of()时没有传入任何值,RxJS 的of()如果没有参数,只会触发subscribe的complete回调,不会触发你写在第一个位置的next回调,因此emit逻辑永远不会执行。
而真实场景中Angular HttpClient的put请求成功时,会先触发一次next回调(值为返回的响应体,这里是void类型的undefined)再触发complete,所以你的组件写法是符合业务逻辑的,问题出在mock的实现上。
额外提示:你提供的服务代码里
unpublishBook方法中引用的libaryId拼写错误,少了一个r,实际开发时需要修正为libraryId,否则运行会报错。
解决方法
修改测试中mock服务返回值的代码,给of()传入一个符合void类型要求的值即可,比如undefined或者null:
// 把原来的两行mock代码改成下面的即可 libraryService.publishBook.mockReturnValue(of(undefined)); libraryService.unpublishBook.mockReturnValue(of(undefined));
修改完成后重新运行测试,bookActionCompleted.emit就会被正确触发,用例可以通过。
可选兼容方案(不推荐修改组件,仅作原理说明)
如果你不想修改mock代码,也可以调整组件内subscribe的写法,把emit逻辑放到complete回调中,这样即使Observable没有发出next值也能触发:
action.subscribe({ complete: () => { this.bookActionCompleted.emit() } });
但这种方式不符合HttpClient的实际行为,所以优先选择修改mock代码的方案。
内容的提问来源于stack exchange,提问作者LozBlake15
相关产品推荐
相关产品推荐

