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

Angular单元测试如何Mock Overlay、OverlayRef与Injector依赖

Angular PopupService 单元测试依赖Mock问题

你编写的PopupService服务实现代码如下:

@Injectable()
export class PopupService {
   private _modal: ModalRef | null = null;
   constructor(private overlay: Overlay,
               private readonly overlayRef: OverlayRef,
               private parentInjector: Injector) {}
   open(data: PopupConfig) {
      const overlayRef = this.overlay.create(this._getModalConfig());
      const modalRef = newModalRef(overlayRef);
      const injector = this._getInjector(data, modelRef, this.parentInjector);
      const portal = new ComponentPortal(PopupComponent, null, injector);
      overlayRef.attach(portal);
      return modalRef;
   }
}

你在为该服务编写单元测试时,不清楚如何在测试的providers配置中MockOverlay、OverlayRef、Injector三个依赖,运行测试时抛出No provider for PopupService报错。
你初步设想的providers配置如下:

providers: [
   Overlay,{provider: Overlay, useValue: fakeOverlay},
   OverlayRef, {provide: OverlayRef, useValue: fakeOverlayRef},
   Injector, {provider: Injector, useValue: fakeInjector}
]

你设想通过jasmine.createSpyObj创建三个间谍对象作为模拟值,对应代码如下:

const fakeOverlay = jasime.createSpyObj('Overlay', []);
const fakeOverlayRef = jasime.createSpyObj('OverlayRef', []);
const fakeInjector = jasime.createSpyObj('Injector', []);

写法问题说明

你的模拟思路整体方向是对的,但存在几处错误导致测试运行失败:

  • 核心报错原因:测试的providers数组中没有加入你要测试的PopupService本身,Angular测试床找不到该服务的注册项就会抛出No provider for PopupService错误。
  • 配置写法错误:providers中同时写原始类名和mock提供项属于重复配置,且存在拼写错误:provider应为provide。
  • 模拟对象创建错误:创建间谍对象的方法名拼写错误,jasime正确写法为jasmine;且创建spy对象时没有把业务代码中会调用到的对应方法加入方法列表,运行时会触发"xxx is not a function"错误。

正确写法参考

1. 创建Mock依赖对象

// 声明mock对象,把业务中调用到的方法加入第二个参数的方法数组
const fakeOverlay = jasmine.createSpyObj<Overlay>('Overlay', ['create']);
const fakeOverlayRef = jasmine.createSpyObj<OverlayRef>('OverlayRef', ['attach']);
const fakeInjector = jasmine.createSpyObj<Injector>('Injector', []);

// 提前定义方法返回值,匹配业务逻辑
fakeOverlay.create.and.returnValue(fakeOverlayRef);

2. 配置测试模块的Providers

providers: [
  PopupService, // 必须注册待测试的服务本身
  { provide: Overlay, useValue: fakeOverlay },
  { provide: OverlayRef, useValue: fakeOverlayRef },
  { provide: Injector, useValue: fakeInjector }
]

额外注意事项
  • 你贴出的服务业务代码本身存在笔误:newModalRef应为实例化ModalRef的正确写法,open方法中传入_getInjector的modelRef是拼写错误,应为modalRef,这两处问题会导致业务代码本身运行报错,需要先修正。
  • 如果后续需要验证服务逻辑,可以通过spy对象的断言方法校验调用参数是否正确,比如验证fakeOverlay.create是否传入了符合预期的弹窗配置、fakeOverlayRef.attach是否传入了正确创建的组件门户实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:21:32