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

测试中如何获取传递给组件的父Injector实例

问题描述

组件中通过构造函数注入私有Injector:

constructor(
    private injector: Injector,
) {}

接着用该实例作为父注入器创建新Injector,用于打开Material对话框:

const dialogRef = this.dialog.open(CoolDialogComponent, {
    data: { /* 自定义数据 */ },
    injector: Injector.create({
        providers: [/* 自定义提供者列表 */],
        parent: this.injector,
    }),
});

测试环节需要验证对话框打开时的参数是否正确,特别是要拿到组件中注入的精确Injector实例作为父注入器来匹配:

expect(dialogSpy.open).toHaveBeenCalledWith(CoolDialogComponent, {
    data: {},
    injector: Injector.create({
        providers: [],
        parent: /* 需要拿到组件中注入的那个Injector实例 */,
    }),
});

尝试过fixture.componentRef.injector、fixture.debugElement.injector、TestBed.inject(Injector)等方法,但都无法获取目标实例。目前只能把组件的injector改成public来获取,希望找到更合理的方案。

TL;DR
测试时如何获取传递给组件的精确Injector实例?


解决方案

1. 自定义提供者捕获Injector实例

在测试配置阶段,通过自定义工厂提供者捕获组件将注入的Injector实例:

let componentInjector: Injector;

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [YourComponent],
    providers: [
      {
        provide: Injector,
        useFactory: (injector: Injector) => {
          componentInjector = injector;
          return injector;
        },
        deps: [Injector]
      }
    ]
  }).compileComponents();
});

组件初始化后,componentInjector就是构造函数中注入的那个私有实例,测试时直接用它做匹配即可:

expect(dialogSpy.open).toHaveBeenCalledWith(CoolDialogComponent, {
    data: {},
    injector: Injector.create({
        providers: [],
        parent: componentInjector,
    }),
});

2. 提前注入测试用Injector实例

直接在TestBed中提供一个可控的Injector实例,让组件构造函数注入这个实例:

let testInjector: Injector;

beforeEach(async () => {
  // 创建或获取测试用Injector实例
  testInjector = TestBed.inject(Injector);
  await TestBed.configureTestingModule({
    declarations: [YourComponent],
    providers: [
      { provide: Injector, useValue: testInjector }
    ]
  }).compileComponents();
});

测试时直接使用testInjector作为父注入器参数,就能精确匹配调用。

3. 非精确匹配(可选)

如果不需要严格验证实例本身,只需要确认参数结构正确,可以用部分匹配语法:

// Jasmine 写法
expect(dialogSpy.open).toHaveBeenCalledWith(CoolDialogComponent, jasmine.objectContaining({
    data: {},
    injector: jasmine.any(Injector)
}));

// Jest 写法
expect(dialogSpy.open).toHaveBeenCalledWith(CoolDialogComponent, expect.objectContaining({
    data: {},
    injector: expect.any(Injector)
}));

这种方式不需要获取精确实例,适合只验证逻辑流程的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:10:54