NestJS控制器currentUser方法单元测试失败及覆盖率问题
测试写法存在的核心问题
你的测试失败、代码未覆盖完全是写法错误导致的,具体问题如下:
- 断言目标错误,根本没有执行被测方法:第二个用例里你写的
expect(controller.currentUser).toEqual("shruti"),是直接把方法本身(函数引用)和字符串"shruti"做对比,完全没有调用currentUser()方法。函数引用永远不可能等于字符串,这是用例失败的直接原因;同时因为方法从未被执行,内部的return request.user行自然不会被执行,覆盖率统计就会标记这行未覆盖。 - 未按方法要求传参:
currentUser方法签名明确要求传入带user属性的Request对象,就算你补了方法调用,不传参会直接触发Cannot read properties of undefined (reading 'user')的运行时错误。你需要手动构造符合预期的mock请求对象作为入参,不要指望框架在手动调用方法时帮你自动注入@Req()修饰的参数——参数注入是Nest处理真实HTTP请求时由路由层完成的,纯控制器实例的单元测试不会触发这套逻辑。 - 测试边界认知错误:你当前的测试模块只注册了控制器本身,
@Roles()权限装饰器、@Get()路由装饰器、@ApiResponse()文档装饰器绑定的框架能力(守卫、路由规则、Swagger文档生成)都不会在这种纯控制器实例的测试中生效。这类和框架运行时绑定的逻辑,需要用supertest做端到端测试才能覆盖,纯单元测试只适合验证控制器方法内部的业务逻辑。
修正后的currentUser测试用例
it('currentUser should return user property from request', () => { // 构造mock请求对象 const mockRequest = { user: "shruti" } as Request; // 传入参数调用被测方法 const result = controller.currentUser(mockRequest); // 断言返回结果 expect(result).toEqual("shruti"); });
补充说明:如果需要验证接口的权限控制、路由匹配、参数装饰器注入等逻辑,不能用当前这种直接实例化控制器的单元测试写法,需要把控制器依赖的守卫、拦截器、管道等全部注册到测试模块,启动Nest测试应用后用HTTP请求模拟的方式测试。
内容的提问来源于stack exchange,提问作者Shruti sharma
相关产品推荐
相关产品推荐

