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

如何对基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:11:08