NestJS Jest测试报错:无法读取undefined的'region'属性
NestJS Jest单元测试中ConfigService无法读取配置的解决方法
在NestJS项目中用Jest编写EmailService的单元测试时,遇到TypeError: Cannot read properties of undefined (reading 'region')错误。测试模块中注入了EmailService和ConfigService,但初始化时失败——EmailService构造函数中通过configService.get('aws')获取的配置为undefined,进而无法读取region属性。
报错代码示例
测试代码:
describe('EmailService', () => { let emailService: EmailService; let configService: ConfigService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [EmailService, ConfigService], }).compile(); emailService = module.get<EmailService>(EmailService); configService = module.get<ConfigService>(ConfigService); }); it('should be defined', () => { expect(emailService).toBeDefined(); }); });
EmailService构造函数:
export class EmailService { private readonly config: IAwsConfig; private readonly region: IRegion; constructor(private readonly configService: ConfigService) { this.config = this.configService.get('aws'); this.region = this.config.region; } }
报错原因
直接在测试模块中声明ConfigService作为provider时,它没有像项目正常运行时那样通过ConfigModule完成初始化——无法加载环境变量或配置文件,导致configService.get('aws')返回undefined,后续访问this.config.region自然抛出错误。
解决方案
方法一:导入并配置ConfigModule(使用真实配置)
在测试模块中导入项目已配置的ConfigModule,让ConfigService能正确读取配置:
describe('EmailService', () => { let emailService: EmailService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [ ConfigModule.forRoot({ isGlobal: true, envFilePath: '.env.test', // 可使用专门的测试环境配置文件 }), ], providers: [EmailService], }).compile(); emailService = module.get<EmailService>(EmailService); }); it('should be defined', () => { expect(emailService).toBeDefined(); }); });
如果项目中ConfigModule已有全局注册或自定义配置(比如用load加载配置文件),直接导入现有模块即可:
imports: [ConfigModule],
方法二:Mock ConfigService(隔离测试,不依赖真实配置)
若不想依赖真实配置文件,可通过Jest模拟ConfigService的get方法,返回预设配置值:
describe('EmailService', () => { let emailService: EmailService; let mockConfigService: jest.Mocked<ConfigService>; beforeEach(async () => { mockConfigService = { get: jest.fn().mockImplementation((key: string) => { if (key === 'aws') { return { region: 'us-east-1' }; // 返回预设的AWS配置 } return null; }), } as jest.Mocked<ConfigService>; const module: TestingModule = await Test.createTestingModule({ providers: [ EmailService, { provide: ConfigService, useValue: mockConfigService, }, ], }).compile(); emailService = module.get<EmailService>(EmailService); }); it('should be defined', () => { expect(emailService).toBeDefined(); }); it('should fetch aws config from ConfigService', () => { expect(mockConfigService.get).toHaveBeenCalledWith('aws'); }); });
这种方式更适合单元测试,能隔离外部依赖,无需加载真实环境变量,测试稳定性更高。
内容的提问来源于stack exchange,提问作者TeModen
相关产品推荐
相关产品推荐

