You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 2-Karma测试:Interceptor中popHttpRequest的spy未被调用问题

问题分析与修复方案

嘿,我一眼就发现问题所在了,咱们一步步来拆解:

核心问题:方法名不匹配

你的拦截器代码里实际调用的是loadOverlayService.start()和loadOverlayService.stop(),但在测试代码中,你给LoadOverlayService mock的是pushHttpRequest和popHttpRequest这两个方法——这俩完全是不同的方法!

拦截器里从来没调用过pushHttpRequest和popHttpRequest,所以你的spy自然会记录调用次数为0,这完全符合预期。

两种修复思路

思路1:直接验证拦截器实际调用的方法

既然拦截器里用的是start和stop,那测试里就应该mock并验证这两个方法:

修改测试中的mock创建代码:

mockLoadOverlayService = jasmine.createSpyObj('LoadOverlayService', ['start', 'stop']);

然后在断言部分改成:

expect(mockLoadOverlayService.start.calls.count()).toBe(1, 'start was called once');
expect(mockLoadOverlayService.stop.calls.count()).toBe(1, 'stop was called once');

思路2:关联start/stop与push/popHttpRequest

如果你的LoadOverlayService内部逻辑是start()会调用pushHttpRequest(),stop()会调用popHttpRequest(),那你需要在mock中模拟这个关联关系:

mockLoadOverlayService = jasmine.createSpyObj('LoadOverlayService', ['start', 'stop', 'pushHttpRequest', 'popHttpRequest']);

// 模拟start内部调用pushHttpRequest
mockLoadOverlayService.start.and.callFake(() => {
  mockLoadOverlayService.pushHttpRequest();
});

// 模拟stop内部调用popHttpRequest
mockLoadOverlayService.stop.and.callFake(() => {
  mockLoadOverlayService.popHttpRequest();
});

这样当拦截器调用start()和stop()时,对应的push/pop方法也会被触发,你的原断言就能正常工作了。

额外小提示

注意RxJS版本的操作符:如果你用的是RxJS 6及以上版本,do操作符已经被重命名为tap了,虽然旧版本的do还能兼容,但建议统一换成tap以避免潜在问题:

return next.handle(request)
  .tap(
    () => {}, // 发出值时的回调,这里不需要处理
    () => this.loadOverlayService.stop(), // 错误时停止
    () => this.loadOverlayService.stop() // 完成时停止
  );

内容的提问来源于stack exchange,提问作者Hidden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:02:45