NestJS API控制器与服务测试方法及单元/集成测试区分
问题解答
1. UsersController 的测试方法及与 UsersService 测试的差异
推荐的 UsersController 测试方法
针对 NestJS 的 Controller 测试,核心是验证HTTP层逻辑,推荐用 Nest 官方的 @nestjs/testing 模块结合 Jest 实现,核心步骤如下:
- 构建测试模块:通过
Test.createTestingModule导入UsersController,并 mock 依赖的UsersService(无需真实实例,仅需验证 Controller 是否正确调用 Service)。 - 验证HTTP交互:可以直接调用 Controller 方法,或用
supertest发起真实HTTP请求,重点验证:- HTTP状态码是否符合预期(比如创建用户返回
201 Created)。 - 请求体是否正确传递给
UsersService.create方法。 - 响应数据的结构、字段是否符合接口定义。
- 异常场景下的错误处理(比如 Service 抛出异常时,Controller 是否返回正确的HTTP错误码)。
- HTTP状态码是否符合预期(比如创建用户返回
示例测试代码片段:
import { Test, TestingModule } from '@nestjs/testing'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; describe('UsersController', () => { let controller: UsersController; let mockUsersService: jest.Mocked<UsersService>; beforeEach(async () => { mockUsersService = { create: jest.fn().mockResolvedValue({ id: 'test-uuid', username: 'test-user', email: 'test@example.com', firstname: 'Test', lastname: 'User', role: 'USER', createdAt: new Date(), updatedAt: new Date(), }), }; const module: TestingModule = await Test.createTestingModule({ controllers: [UsersController], providers: [{ provide: UsersService, useValue: mockUsersService }], }).compile(); controller = module.get<UsersController>(UsersController); }); it('should call UsersService.create and return user data', async () => { const createUserDto = { username: 'test-user', email: 'test@example.com', firstname: 'Test', lastname: 'User', password: 'test-pass', }; const result = await controller.create(createUserDto); expect(mockUsersService.create).toHaveBeenCalledWith(createUserDto); expect(result).toHaveProperty('id'); expect(result).not.toHaveProperty('password'); }); });
与 UsersService 测试的差异
| 维度 | UsersController 测试 | UsersService 测试 |
|---|---|---|
| 测试核心 | HTTP层交互(状态码、请求响应格式) | 业务逻辑(数据校验、密码哈希、数据处理) |
| 依赖处理 | Mock 所有上层依赖(如 UsersService) | Mock 底层依赖(如 Prisma 客户端) |
| 关注点 | 验证请求转发、响应格式的正确性 | 验证业务规则、数据处理的准确性 |
2. 单元测试与集成测试的区别,及 UsersService 测试的归类
单元测试 vs 集成测试
- 单元测试:
- 聚焦单个独立组件(如单个Service方法、单个Controller方法)。
- 完全隔离外部依赖(用mock/stub替代)。
- 粒度细、执行快,目标是验证组件自身逻辑的正确性。
- 集成测试:
- 验证多个组件的协作逻辑(如 Controller + Service + 数据库),或组件与外部系统的交互。
- 使用真实依赖(如测试数据库、真实Prisma客户端)。
- 覆盖端到端流程,目标是验证组件组合后的整体功能是否正常。
UsersService 测试的归类
- 如果测试时Mock了Prisma客户端,仅验证Service内部的密码哈希、数据校验、返回字段过滤等逻辑,属于单元测试。
- 如果使用真实测试数据库,直接调用Prisma执行数据操作,验证Service与数据库的交互逻辑,属于集成测试。
通常纯业务逻辑的Service测试以单元测试为主,数据库交互的验证会用集成测试补充。
内容的提问来源于stack exchange,提问作者Sn0w
相关产品推荐
相关产品推荐

