Angular独立组件测试报错:Injection Token无提供者求助
问题场景
我有一个Angular独立组件,依赖ICON_SVG_PATH这个Injection Token配置资源路径(微前端场景下不同应用路径不同)。组件本身未提供该令牌,需在外部模块(如app-module.ts)中通过providers覆盖注入值。
组件构造函数:
constructor( @Inject(ICON_SVG_PATH) public iconSvgPath: string, private readonly renderer: Renderer2 ) {}
正常使用组件时(比如Storybook),只需导入组件并在providers中提供令牌即可正常运行:
imports: [IconComponent], providers: [ { provide: ICON_SVG_PATH, useValue: '/assets/icons', }, ],
但在组件的spec.ts测试文件中,出现以下注入错误:
NullInjectorError: R3InjectorError(Standalone[IconComponent])[InjectionToken ICON_SVG_PATH -> InjectionToken ICON_SVG_PATH -> InjectionToken ICON_SVG_PATH]:
NullInjectorError: No provider for InjectionToken ICON_SVG_PATH!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'InjectionToken ICON_SVG_PATH', 'InjectionToken ICON_SVG_PATH', 'InjectionToken ICON_SVG_PATH' ] })
尝试过以下三种方式均无效:
- 在TestBed的
providers中直接添加令牌配置 - 使用
TestBed.overrideProvider方法修改提供者 - 在
test.ts中全局配置令牌提供者
解决方案
核心原因是独立组件拥有自己的私有注入上下文,根注入器的配置无法直接覆盖组件的依赖。需针对组件的注入上下文进行配置,以下两种方法均可解决:
方法1:通过overrideComponent为组件添加提供者
直接修改组件自身的providers配置,确保注入上下文能获取到令牌值:
await TestBed.configureTestingModule({ imports: [IconComponent], }) .overrideComponent(IconComponent, { set: { changeDetection: ChangeDetectionStrategy.Default, providers: [ { provide: ICON_SVG_PATH, useValue: '/assets/icons' } ] } }) .compileComponents();
方法2:使用withProviders导入组件(Angular 14+)
如果你的Angular版本是14及以上,可利用独立组件的withProvidersAPI,在导入时直接附带依赖配置:
await TestBed.configureTestingModule({ imports: [ IconComponent.withProviders([ { provide: ICON_SVG_PATH, useValue: '/assets/icons' } ]) ], }) .overrideComponent(IconComponent, { set: { changeDetection: ChangeDetectionStrategy.Default }, }) .compileComponents();
错误尝试的原因说明
- 直接在TestBed的
providers中添加:根注入器的配置无法渗透到独立组件的私有注入上下文 - 使用
overrideProvider:该方法仅修改根注入器的提供者,不作用于组件的私有注入上下文 - 全局配置令牌:同样是作用于根注入器,无法覆盖组件的私有依赖
内容的提问来源于stack exchange,提问作者Flavien Cossu

