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

Angular 19无Zone环境Jest测试守卫遇NullInjectorError配置注入问题

解决Angular 19无Zone环境下Jest测试守卫的NullInjectorError错误

你遇到的NullInjectorError: No provider for InjectionToken Application Configuration!错误,核心原因是setLanguage守卫函数依赖了Application Configuration注入令牌,但测试模块里没提供对应的模拟实现。

解决步骤

  1. 先确认项目中Application Configuration对应的注入令牌定义(一般是一个InjectionToken,比如在app-config.ts这类文件中):
export const APP_CONFIG = new InjectionToken('Application Configuration');
  1. 在测试模块的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:25:03