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

如何在测试Angular 2组件时模拟@Inject注入的服务?

如何在Angular组件测试中模拟多个注入服务,包括通过@Inject('sitService')注入的服务?

我有一个组件,其构造函数签名如下:

constructor(
  private loremApiService: LoremApiService,
  private ipsumService: IpsumService,
  private dolorService: DolorService,
  @Inject('sitService') private sitService: library.service.Service
) { }

该组件的测试文件已做如下配置:

let component: PowerBiReportComponent;
let fixture: ComponentFixture<TestingComponent>;
const mockLoremApi = { methodThatIsCalled: () => {} };
const mockIpsumService = { };
const mockSitService = { };
beforeEach(...

请问如何模拟这些注入的服务,尤其是通过@Inject('sitService')注入的服务?


解决方案

在Angular测试里,不管是类注入的服务还是通过令牌(@Inject)注入的服务,都可以通过TestBed.configureTestingModule来统一配置模拟对象,具体步骤如下:

1. 补全模拟对象(按需)

先确保每个模拟服务包含组件实际用到的方法或属性——如果组件调用了某个服务的特定方法,你的模拟对象里得有对应的占位,比如如果DolorService有个getData方法,就补充:

const mockDolorService = { getData: () => of('mock response') };

2. 在TestBed中配置Providers

在beforeEach的测试模块配置里,用providers数组把真实服务替换成你的模拟对象:

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [PowerBiReportComponent], // 替换为你的组件类
    providers: [
      // 处理普通类注入的服务:用useValue指向你定义的mock对象
      { provide: LoremApiService, useValue: mockLoremApi },
      { provide: IpsumService, useValue: mockIpsumService },
      { provide: DolorService, useValue: mockDolorService },
      // 处理@Inject('sitService')的服务:
      // provide的值必须和@Inject括号里的令牌字符串完全一致
      { provide: 'sitService', useValue: mockSitService }
    ]
  }).compileComponents();

  fixture = TestBed.createComponent(PowerBiReportComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});

3. 验证模拟服务的调用(可选)

如果要确认组件是否正确调用了模拟服务的方法,可以用Jasmine的spyOn监听:

it('should trigger methodThatIsCalled when component method runs', () => {
  spyOn(mockLoremApi, 'methodThatIsCalled');
  // 触发组件里调用该服务方法的逻辑
  component.triggerServiceCall();
  expect(mockLoremApi.methodThatIsCalled).toHaveBeenCalled();
});

关键注意事项

  • 对于@Inject注入的服务,provide的字符串必须和构造函数里@Inject的令牌完全匹配,大小写也不能错。
  • 如果模拟服务需要返回异步数据(比如Observable),记得引入RxJS的操作符(比如of)来模拟返回值。
  • 如果服务是providedIn: 'root'全局注册的,测试时也必须显式在providers里替换,否则TestBed会使用真实的服务实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:46:16