Angular+Cypress组件测试:InjectionToken提供者存在却报错解决
问题
在Nx Angular应用中编写Cypress组件测试时,已为DASHBOARD_TOKEN注入令牌配置提供者,但测试运行时提示NullInjectorError: No provider for InjectionToken Dashbaord!。
注入令牌定义
export const DASHBOARD_TOKEN = new InjectionToken<DashboardService>('Dashbaord');
测试代码
let data: Project | undefined; let dashboard: DashboardService; before(function () { cy.fixture('project.json').then(function (json) { data = json; }); }); describe(ArrowChartComponent.name, () => { beforeEach(() => { TestBed.overrideComponent(ArrowChartComponent, { add: { imports: [ArrowChartModule], providers: [ { provide: DASHBOARD_TOKEN, useClass: DashboardService }, { provide: EVENT_SERVICE_TOKEN, useClass: EventService }, ], }, }); dashboard = TestBed.inject(DASHBOARD_TOKEN); }); it('renders', () => { cy.mount(ArrowChartComponent, { componentProperties: { id: 0, width: 0, height: 0, rebuild: false, showFastCreator: true, }, }); }); });
报错信息
"before each" hook for "renders": NullInjectorError: R3InjectorError(CompilerModule)[InjectionToken Dashbaord -> InjectionToken Dashbaord]: NullInjectorError: No provider for InjectionToken Dashbaord!
报错原因
- Cypress
cy.mount与Angular TestBed上下文隔离:通过TestBed.overrideComponent配置的提供者不会被cy.mount复用。cy.mount会创建独立的测试模块上下文,完全忽略外部TestBed的修改。 - 过早调用
TestBed.inject:在cy.mount执行前调用TestBed.inject时,组件的测试注入器还未初始化,此时提供者未被注册,自然无法解析令牌。
解决方法
将提供者配置直接传入cy.mount的配置参数中,若需获取服务实例,需在组件挂载完成后通过Cypress的Angular工具获取:
let data: Project | undefined; let dashboard: DashboardService; before(function () { cy.fixture('project.json').then(function (json) { data = json; }); }); describe(ArrowChartComponent.name, () => { it('renders', () => { cy.mount(ArrowChartComponent, { imports: [ArrowChartModule], providers: [ { provide: DASHBOARD_TOKEN, useClass: DashboardService }, { provide: EVENT_SERVICE_TOKEN, useClass: EventService }, ], componentProperties: { id: 0, width: 0, height: 0, rebuild: false, showFastCreator: true, }, }); // 挂载完成后获取服务实例 cy.getAngularService(DASHBOARD_TOKEN).then(service => { dashboard = service; // 可在此添加对服务的断言或操作 }); }); });
另外,注意令牌定义中的拼写错误:'Dashbaord'应为'Dashboard',虽然当前报错并非由此导致,但修正拼写可避免后续潜在问题。
内容的提问来源于stack exchange,提问作者afriedman111
相关产品推荐
相关产品推荐

