测试中无法Mock NestJS Guard依赖的问题求助
问题分析与解决方案
你的测试失败的核心原因是HTTP请求头字段在Node.js/Express中会被自动规范化,导致Guard中无法正确获取到你设置的STARLIGHT_SESSION_ID头。
具体问题
当你用supertest的.set('STARLIGHT_SESSION_ID', sessionId)设置请求头时,Node.js的HTTP模块会将头字段名规范化为小写,并且将下划线转换为连字符,最终在request.headers中对应的键是starlight-session-id,而非你代码中写的STARLIGHT_SESSION_ID。这直接导致starlightSessionId变量为undefined,触发UnauthorizedException返回401。
修复方案
修改AuthenticationGuard中获取请求头的方式,改用Express提供的request.get()方法——这个方法会自动处理头字段的大小写和格式差异,更可靠:
// authentication.guard.ts canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> { const request = context.switchToHttp().getRequest(); // 改用request.get()获取头,不区分大小写 const starlightSessionId = request.get('STARLIGHT_SESSION_ID'); if (typeof starlightSessionId !== 'string') throw new UnauthorizedException('Authentication failed!'); const session = this.sessionService.getEmployeeSession(starlightSessionId); if (!session) throw new UnauthorizedException('Authentication failed!'); return true; }
可选替代方案
如果你坚持直接访问request.headers,也可以使用规范化后的键名:
const starlightSessionId = request.headers['starlight-session-id'];
但request.get()是更通用的做法,无需关心头字段的大小写和格式转换细节。
测试代码确认
你的第三个测试中,SessionService的注入方式是正确的——创建实例后通过useValue传入,确保Guard使用的是同一个包含有效会话的实例。修复头字段获取逻辑后,这个测试应该能正常通过。
内容的提问来源于stack exchange,提问作者melosomelo
相关产品推荐
相关产品推荐

