NestJS单元测试出现循环依赖报错,项目运行正常求原因
NestJS单元测试中循环依赖导致的
enumToDescription未定义问题 问题描述
在NestJS项目中,项目本身运行无异常,但运行单元测试时出现如下错误:
TypeError: Cannot read properties of undefined (reading 'enumToDescription') 6 | export class ChannelUser { 7 | @ApiProperty({ 8 | description: SwaggerHelper.enumToDescription(UserAccessEnum),
经排查,问题源于循环依赖:原本SwaggerHelper是从index.ts文件导入的,改为直接从对应文件导入后问题解决。现咨询为何该错误仅在单元测试场景中出现,单元测试代码如下:
describe('Auth Service', () => { let authService: AuthService; beforeAll(async () => { const testModule = await Test.createTestingModule({ imports: [UsersModule, GlobalModule], }).compile(); authService = testModule.get(AuthService); }); describe('Refresh token', () => { expect(authService.refreshTokens({token: '123'})).toBe('11'); }); });
原因分析
- 模块加载逻辑差异:项目正常运行时,NestJS生产环境的模块加载机制会通过延迟加载、代理对象等方式自动处理循环依赖。但单元测试中用
Test.createTestingModule构建的测试容器,加载逻辑更直接严格,不会自动兼容复杂的循环依赖场景。当通过index.ts中转导入SwaggerHelper时,若存在反向引用链,测试容器初始化时SwaggerHelper还未完成初始化就被ChannelUser的装饰器调用,导致undefined错误。 - 装饰器执行时机影响:
@ApiProperty装饰器在类定义阶段就会执行,而非运行时。单元测试编译模块时会立即解析所有类的装饰器代码,若SwaggerHelper通过index.ts导入且存在循环依赖,装饰器执行时SwaggerHelper还未被正确赋值。而生产环境的预编译和加载流程会确保依赖在装饰器执行前完成初始化。 - 测试容器的隔离性:单元测试的测试容器是独立构建的,不会复用生产环境的模块缓存或加载逻辑。生产环境中被隐式处理的依赖问题,在测试环境中会直接暴露。直接从对应文件导入
SwaggerHelper打破了循环依赖链,让依赖关系更明确,测试容器能正确解析初始化。
内容的提问来源于stack exchange,提问作者rostamiani
相关产品推荐
相关产品推荐

