NestJS运行E2E测试时出现Reflect.getMetadata TypeError的解决咨询
NestJS E2E测试替换模块后仍报错的解决选项
报错信息
[Nest] 163363 - 10/03/2022, 11:59:37 AM LOG [NestFactory] Starting Nest application... [Nest] 163363 - 10/03/2022, 11:59:37 AM ERROR [ExceptionHandler] TypeError at Reflect.getMetadata (/home/mszan/foo/source/node_modules/reflect-metadata/Reflect.js:354:23) at DependenciesScanner.isInjectable (/home/mszan/foo/source/node_modules/@nestjs/core/scanner.js:302:26) at DependenciesScanner.insertModule (/home/mszan/foo/source/node_modules/@nestjs/core/scanner.js:73:18) at DependenciesScanner.scanForModules (/home/mszan/foo/source/node_modules/@nestjs/core/scanner.js:34:43) at DependenciesScanner.scan (/home/mszan/foo/source/node_modules/@nestjs/core/scanner.js:27:20) at async /home/mszan/foo/source/node_modules/@nestjs/core/nest-factory.js:95:17 at async Function.asyncRun (/home/mszan/foo/source/node_modules/@nestjs/core/errors/exceptions-zone.js:22:13) at async NestFactoryStatic.initialize (/home/mszan/foo/source/node_modules/@nestjs/core/nest-factory.js:94:13) at async NestFactoryStatic.create (/home/mszan/foo/source/node_modules/@nestjs/core/nest-factory.js:37:9) ● process.exit called with "1" at DEFAULT_TEARDOWN (../../node_modules/@nestjs/core/errors/exceptions-zone.js:6:40) at Function.asyncRun (../../node_modules/@nestjs/core/errors/exceptions-zone.js:29:13) at async NestFactoryStatic.initialize (../../node_modules/@nestjs/core/nest-factory.js:94:13) at async NestFactoryStatic.create (../../node_modules/@nestjs/core/nest-factory.js:37:9)
测试代码(app.e2e-spec.ts)
describe('app - e2e', () => { let app: INestApplication; beforeAll(async () => { const moduleRef: TestingModule = await Test.createTestingModule({ ...appModuleMetadata, imports: appModuleMetadata.imports.map((x) => { if (x == CommonModule) { return CommonModuleMock; } return x; }), }).compile(); app = moduleRef.createNestApplication(); await app.init(); }); });
问题详情
CommonModule包含一个依赖fs和path包的Provider,移除这些依赖后测试可正常运行。但尝试用不含上述依赖的CommonModuleMock替换原CommonModule时,测试仍抛出上述错误。当前环境版本:Nest 9.0.11、Jest 29.0.3、Supertest 6.2.4、Node 16.17.0。
解决选项
- 检查CommonModuleMock的模块定义规范:确保Mock模块用
@Module()装饰器正确包裹,内部的Provider、导出项等配置符合NestJS模块要求。如果Mock模块结构不合法,依赖扫描器会无法识别,抛出Reflect相关错误。 - 改用
overrideModule替换模块:放弃手动遍历imports数组的方式,使用NestJS测试工具提供的overrideModuleAPI,更可靠地替换目标模块:const moduleRef: TestingModule = await Test.createTestingModule(appModuleMetadata) .overrideModule(CommonModule) .useModule(CommonModuleMock) .compile(); - 排查Mock模块的间接依赖:检查CommonModuleMock的imports或Provider是否意外引入了原CommonModule的内容,导致原模块的
fs/path依赖仍被加载。 - 清理Jest缓存:Jest可能缓存了旧的模块编译结果,执行
jest --clearCache后重新运行测试,排除缓存导致的问题。 - 校验reflect-metadata版本兼容性:NestJS 9对reflect-metadata有版本要求,确保项目中该包的版本与
@nestjs/core兼容,可尝试重新安装依赖:rm -rf node_modules package-lock.json && npm install。 - 仅Mock问题Provider而非整个模块:如果替换整个模块成本高,可只MockCommonModule中依赖
fs/path的那个Provider,保留模块其他部分:const moduleRef: TestingModule = await Test.createTestingModule(appModuleMetadata) .overrideProvider(ProblematicProvider) .useValue(mockProviderInstance) .compile();
内容的提问来源于stack exchange,提问作者mszan
相关产品推荐
相关产品推荐

