如何为基于GRPC的NestJS微服务编写集成/端到端测试?
NestJS gRPC微服务集成测试实现方案
问题背景
我有一个用gRPC实现微服务通信的NestJS应用,需要为部分端点编写集成/端到端测试(仅模拟外部微服务调用、数据库调用等)。但NestJS官方文档只覆盖了REST应用的集成测试,现有代码如下:
Controller文件
import { ClassSerializerInterceptor, Controller, Logger, UseFilters, UseInterceptors, } from '@nestjs/common'; import { GrpcMethod } from '@nestjs/microservices'; import { RpcValidationFilter } from '../../common/exception/filters/rpc.filter'; enum GrpcService { NAME = 'TestService', } export class TestDto { userId: string; constructor() { this.userId = 'userId'; } } @Controller() @UseFilters(RpcValidationFilter) @UseInterceptors(ClassSerializerInterceptor) export class TestController { private readonly logger = new Logger(TestController.name); constructor() {} @GrpcMethod(GrpcService.NAME) public testProto(data: TestDto): Promise<TestDto> { this.logger.debug(data, 'Testing GRPC method call'); return Promise.resolve(new TestDto()); } }
Proto文件
syntax = "proto3"; package testProto.v1; service TestService { rpc TestProto (RequestDto) returns (ResponseDto); } message RequestDto { string user_id = 1; } message ResponseDto { string user_id = 1; }
需要创建应用实例并发送gRPC请求调用控制器方法,无服务层/数据库层,该如何实现?
实现步骤
1. 安装必要依赖
确保项目已安装测试相关依赖,若未安装执行:
npm install --save-dev @nestjs/testing @grpc/grpc-js @grpc/proto-loader
2. 编写集成测试文件
在test目录下创建test.controller.e2e-spec.ts,代码如下:
import { Test } from '@nestjs/testing'; import { loadPackageDefinition, credentials } from '@grpc/grpc-js'; import { loadSync } from '@grpc/proto-loader'; import { TestController } from '../src/test/test.controller'; describe('TestController (gRPC)', () => { let client: any; let app: any; beforeAll(async () => { // 创建测试模块,注入目标控制器 const moduleRef = await Test.createTestingModule({ controllers: [TestController], }).compile(); // 启动gRPC微服务,监听随机端口避免冲突 app = moduleRef.createNestMicroservice({ transport: 'grpc', options: { package: 'testProto.v1', protoPath: './src/test/test.proto', // 替换为你的proto文件实际路径 url: 'localhost:0', }, }); await app.listen(); // 获取微服务实际地址,创建gRPC客户端 const serverUrl = app.getUrl(); const protoDefinition = loadSync('./src/test/test.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true, }); const testProto = loadPackageDefinition(protoDefinition).testProto.v1; client = new testProto.TestService(serverUrl, credentials.createInsecure()); }); afterAll(async () => { // 清理资源:关闭客户端和微服务 client.close(); await app.close(); }); it('should return expected TestDto when calling TestProto', (done) => { const request = { user_id: 'test-user-123' }; // 调用gRPC方法并验证结果 client.testProto(request, (error: any, response: any) => { expect(error).toBeNull(); expect(response.user_id).toBe('userId'); done(); }); }); });
3. 关键逻辑说明
- 测试环境搭建:通过
Test.createTestingModule模拟应用容器,仅注入需要测试的控制器,保证测试隔离性。 - 微服务启动:使用
createNestMicroservice创建gRPC服务实例,指定url: 'localhost:0'让系统自动分配可用端口,避免端口占用冲突。 - 客户端初始化:加载proto文件生成客户端定义,连接到测试微服务的实际地址,实现gRPC请求调用。
- 异步测试处理:gRPC调用为异步操作,使用
done回调通知测试框架异步逻辑完成。
4. 运行测试
确保package.json中包含e2e测试命令:
{ "scripts": { "test:e2e": "jest --config ./test/jest-e2e.json" } }
执行测试命令:
npm run test:e2e
内容的提问来源于stack exchange,提问作者Caroline
相关产品推荐
相关产品推荐

