Azure SSO集成后PR构建失败:NullInjectorError: No provider for MsalService
解决Azure SSO集成后单元测试的
NullInjectorError问题 问题描述
集成Azure SSO后,PR构建在执行单元测试命令ng test --watch=false --code-coverage=false --browsers=ChromeHeadless时失败,报错NullInjectorError: No provider for MsalService!,最终返回:
##[error]Error: Npm failed with return code: 1
核心原因
单元测试环境与生产环境是独立的,你的AppModule中配置的Msal依赖未在测试用例的TestBed中正确加载,导致测试时无法注入MsalService。
解决步骤
1. 在组件测试文件中配置Msal依赖
对使用了MsalService的组件,需在测试的TestBed中导入MsalModule并提供必要的依赖:
import { TestBed } from '@angular/core/testing'; import { MsalModule, MSAL_INSTANCE, MsalService } from '@azure/msal-angular'; import { IPublicClientApplication, PublicClientApplication } from '@azure/msal-browser'; import { msalConfig } from '../auth-config'; // 复用生产环境的实例工厂 const MSALInstanceFactory = (): IPublicClientApplication => new PublicClientApplication(msalConfig()); describe('目标组件', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [MsalModule], providers: [ { provide: MSAL_INSTANCE, useFactory: MSALInstanceFactory }, MsalService ] }).compileComponents(); }); // 编写测试用例... });
2. 使用模拟服务简化测试
若不想加载真实的MsalService,可创建模拟类替代,避免依赖外部配置:
// 模拟MsalService的核心方法 class MockMsalService { loginPopup() { return Promise.resolve({}); } acquireTokenSilent() { return Promise.resolve({ accessToken: 'mock-token' }); } // 按需添加其他需要模拟的方法 } describe('目标组件', () => { beforeEach(async () => { await TestBed.configureTestingModule({ providers: [ { provide: MsalService, useClass: MockMsalService } ] }).compileComponents(); }); });
3. 解决auth-config.ts的依赖问题
你的auth-config.ts依赖AuthService的静态方法,测试环境下需确保这些方法能正常返回值,可通过Spy模拟:
import { AuthService } from './auth/auth.service'; beforeEach(() => { // 模拟静态方法返回测试用的配置值 spyOn(AuthService, 'getClientId').and.returnValue('mock-client-id'); spyOn(AuthService, 'getDirectoryIdUrl').and.returnValue('https://mock-authority-url'); });
4. 全局复用测试配置(可选)
若多个测试文件都需要Msal依赖,可创建全局测试模块统一配置:
// 创建test-msal.module.ts import { NgModule } from '@angular/core'; import { MsalModule, MSAL_INSTANCE, MsalService } from '@azure/msal-angular'; import { IPublicClientApplication, PublicClientApplication } from '@azure/msal-browser'; import { msalConfig } from './auth-config'; const MSALInstanceFactory = (): IPublicClientApplication => new PublicClientApplication(msalConfig()); @NgModule({ imports: [MsalModule], providers: [ { provide: MSAL_INSTANCE, useFactory: MSALInstanceFactory }, MsalService ] }) export class TestMsalModule {}
之后在测试文件中直接导入TestMsalModule即可。
内容的提问来源于stack exchange,提问作者Priyank Pahuja
相关产品推荐
相关产品推荐

