NestJS测试报错:Cannot read property 'getRequestId' of undefined 求助
问题解决:测试中RequestIdProvider注入失败导致的TypeError
错误原因
测试环境没有真实的HTTP请求上下文,而RequestIdProvider是**请求作用域(Scope.REQUEST)**的服务,它依赖@Inject(REQUEST)获取请求对象。直接在测试模块中注册真实的RequestIdProvider时,Nest无法在无请求的环境下实例化该服务,导致AppLogger中的requestIdProvider为undefined,调用getRequestId()时触发报错。
另外你的测试代码还存在两个小问题:
- 控制器注册时写了
RolesController,应该是MyController - 测试模块创建后缺少
.compile()方法,导致模块未正确编译
解决方案
方案1:Mock RequestIdProvider(推荐)
直接模拟RequestIdProvider的实现,不需要依赖真实请求上下文,适合单元测试场景:
describe('MyController', () => { let controller: MyController; let service: MyService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [MyController], providers: [ MyService, // Mock RequestIdProvider,返回固定测试用请求ID { provide: RequestIdProvider, useValue: { getRequestId: () => 'test-fake-request-id' } }, AppLogger ], }).compile(); // 补上缺失的compile方法 controller = module.get<MyController>(MyController); service = module.get<MyService>(MyService); }); // 测试用例... });
方案2:模拟REQUEST对象
如果需要保留RequestIdProvider的真实逻辑,可以模拟一个带有requestId的请求对象注入:
describe('MyController', () => { let controller: MyController; let service: MyService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [MyController], providers: [ MyService, RequestIdProvider, AppLogger, // 模拟REQUEST对象,提供requestId字段 { provide: REQUEST, useValue: { requestId: 'test-fake-request-id' } } ], }).compile(); controller = module.get<MyController>(MyController); service = module.get<MyService>(MyService); }); // 测试用例... });
关键说明
- 单元测试的核心是隔离依赖,所以优先推荐方案1,避免引入不必要的上下文依赖
- 确保测试模块创建后调用
.compile(),否则Nest无法完成provider的注入逻辑
内容的提问来源于stack exchange,提问作者Code Guru
相关产品推荐
相关产品推荐

