You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试中无法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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 16:30:16