Angular 19无Zone环境Jest测试守卫遇NullInjectorError配置注入问题
解决Angular 19无Zone环境下Jest测试守卫的NullInjectorError错误
你遇到的NullInjectorError: No provider for InjectionToken Application Configuration!错误,核心原因是setLanguage守卫函数依赖了Application Configuration注入令牌,但测试模块里没提供对应的模拟实现。
解决步骤
- 先确认项目中
Application Configuration对应的注入令牌定义(一般是一个InjectionToken,比如在app-config.ts这类文件中):
export const APP_CONFIG = new InjectionToken('Application Configuration');
- 在测试模块的
providers数组中添加该令牌的模拟值,根据实际配置结构提供对应对象:
修改你的测试代码,在TestBed.configureTestingModule的providers中新增模拟配置:
import { beforeEach, describe, expect, it, jest } from '@jest/globals'; import { provideMockStore } from '@ngrx/store/testing'; import { TestBed } from '@angular/core/testing'; import { setLanguage } from './index'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; import { provideExperimentalZonelessChangeDetection } from '@angular/core'; import { TranslocoService } from '@jsverse/transloco'; import { provideHttpClient } from '@angular/common/http'; import { APP_CONFIG } from './path-to-your-app-config'; // 替换为实际文件路径 describe('setLanguage', () => { let activatedRouteSnapshotMock: ActivatedRouteSnapshot; let translocoServiceMock: jest.Mocked<TranslocoService>; const initialState = { setLanguage: jest.fn(), setInitialized: jest.fn(), }; beforeEach(() => { translocoServiceMock = { setActiveLang: jest.fn(), load: jest.fn() } as any; TestBed.configureTestingModule({ providers: [ provideMockStore({ initialState }), { provide: Router, useValue: { navigate: jest.fn(), }, }, { provide: TranslocoService, useValue: translocoServiceMock }, provideExperimentalZonelessChangeDetection(), provideHttpClient(), // 新增:模拟Application Configuration注入令牌 { provide: APP_CONFIG, useValue: { defaultLang: 'en', // 示例字段,替换为你的实际配置项 // ...其他需要的配置内容 } } ], }); activatedRouteSnapshotMock = { params: { lang: 'xy' }, } as unknown as ActivatedRouteSnapshot; }); it('should return true if the new language is already set', () => { activatedRouteSnapshotMock.params['lang'] = 'en'; TestBed.runInInjectionContext(() => { expect(setLanguage(activatedRouteSnapshotMock)).toEqual(true); }); }); });
原因说明
Angular的依赖注入系统(包括无Zone实验性环境)要求所有被注入的依赖,必须在当前注入上下文提供对应的提供者。你的setLanguage守卫执行时会尝试注入Application Configuration,因此测试环境必须显式提供这个依赖的模拟,否则就会抛出找不到提供者的错误。
内容的提问来源于stack exchange,提问作者GinoMartino
相关产品推荐
相关产品推荐

