如何对基于Fastify的Nest项目中的main.ts进行单元测试?
如何对Nest的main.ts进行单元测试
核心思路
main.ts里的bootstrap是自执行函数,测试时需要先导出它,再通过Jest模拟所有外部依赖(避免实际启动服务),验证每个关键步骤是否正确执行。
步骤1:修改main.ts导出bootstrap函数
先把bootstrap函数导出,方便测试文件调用:
export async function bootstrap() { const app = await NestFactory.create<NestFastifyApplication>( AppModule, new FastifyAdapter(), ); app.useGlobalPipes(new ValidationPipe()); const config = new DocumentBuilder() .setTitle('Api') .addTag('Api', 'User API') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('user', app, document); await app.listen(process.env.CONTAINER_PORT, '0.0.0.0'); console.log(`port: ${process.env.EXTERNAL_PORT}`); } bootstrap();
步骤2:编写测试文件main.spec.ts
用Jest模拟所有依赖,验证每个逻辑节点:
import { bootstrap } from './main'; import { NestFactory } from '@nestjs/core'; import { FastifyAdapter } from '@nestjs/platform-fastify'; import { ValidationPipe } from '@nestjs/common'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; // 模拟环境变量 process.env.CONTAINER_PORT = '3000'; process.env.EXTERNAL_PORT = '8080'; // 模拟Nest核心模块 jest.mock('@nestjs/core', () => ({ NestFactory: { create: jest.fn().mockResolvedValue({ useGlobalPipes: jest.fn(), listen: jest.fn().mockResolvedValue(true), }), }, })); // 模拟Fastify适配器 jest.mock('@nestjs/platform-fastify', () => ({ FastifyAdapter: jest.fn(), })); // 模拟ValidationPipe jest.mock('@nestjs/common', () => ({ ValidationPipe: jest.fn(), })); // 模拟Swagger相关模块 jest.mock('@nestjs/swagger', () => ({ DocumentBuilder: { setTitle: jest.fn().mockReturnThis(), addTag: jest.fn().mockReturnThis(), build: jest.fn().mockReturnValue({}), }, SwaggerModule: { createDocument: jest.fn().mockReturnValue({}), setup: jest.fn(), }, })); // 模拟console.log global.console.log = jest.fn(); describe('bootstrap', () => { it('should initialize app with correct configurations', async () => { await bootstrap(); // 验证应用创建逻辑 expect(NestFactory.create).toHaveBeenCalledWith( expect.any(Function), expect.any(FastifyAdapter), ); // 验证全局管道设置 const appInstance = (NestFactory.create as jest.Mock).mock.results[0].value; expect(appInstance.useGlobalPipes).toHaveBeenCalledWith(expect.any(ValidationPipe)); // 验证Swagger配置流程 expect(DocumentBuilder.setTitle).toHaveBeenCalledWith('Api'); expect(DocumentBuilder.addTag).toHaveBeenCalledWith('Api', 'User API'); expect(SwaggerModule.createDocument).toHaveBeenCalledWith(appInstance, {}); expect(SwaggerModule.setup).toHaveBeenCalledWith('user', appInstance, {}); // 验证端口监听 expect(appInstance.listen).toHaveBeenCalledWith('3000', '0.0.0.0'); // 验证日志输出 expect(console.log).toHaveBeenCalledWith('port: 8080'); }); });
关键注意点
- 所有外部依赖必须用
jest.mock模拟,避免测试时实际启动服务或创建资源 - 导出
bootstrap函数是测试的前提,否则无法在测试中直接调用执行 - 测试用例要覆盖所有核心逻辑:应用初始化、管道配置、Swagger设置、端口监听、日志输出
内容的提问来源于stack exchange,提问作者João Fragoso
相关产品推荐
相关产品推荐

