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

如何在Jest作用域之外启动含Mock模块的NestJS服务?

解决Jest作用域外启动NestJS服务并沿用Mock模块的问题

核心问题分析

你用jest.mock()这类Jest专属语法定义的Mock,仅能在Jest运行环境中被识别。直接用ts-node执行run.ts时,由于没有加载Jest的全局上下文,必然会抛出jest is not defined错误。要复用Mock逻辑,必须将Mock从Jest依赖中解耦。

具体解决方案

方案1:将Mock逻辑改为独立模块(推荐)

把原本用jest.mock()实现的Mock,重构为独立的模拟模块,在启动服务时手动引入替换:

  1. 提取Mock模块
    比如原代码用jest.mock('./external-service', () => ({ ... })),现在新建__mocks__/external-service.ts文件,写入Mock实现:

    // __mocks__/external-service.ts
    export const ExternalService = {
      getRemoteData: jest.fn().mockResolvedValue({ mockData: 'test' })
    };
    

    这里暂时保留jest.fn(),后续会在非Jest环境中模拟全局jest对象。

  2. 在启动脚本中手动替换依赖
    在run.ts里,通过require.cache将真实模块替换为Mock模块:

    // run.ts
    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './src/app.module';
    
    // 手动加载Mock模块,覆盖真实模块的缓存
    const mockModule = require('./__mocks__/external-service');
    require.cache[require.resolve('./src/external-service')] = {
      exports: mockModule
    };
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      await app.listen(3000);
      console.log('NestJS server running on http://localhost:3000');
    }
    bootstrap();
    
  3. 为非Jest环境模拟全局Jest对象
    在run.ts最顶部添加全局jest模拟,避免jest.fn()报错:

    // run.ts 顶部
    global.jest = {
      fn: () => {
        const mockFn = (...args: any[]) => {
          if (mockFn.mockImplementation) {
            return mockFn.mockImplementation(...args);
          }
          return mockFn;
        };
        mockFn.mockResolvedValue = (value: any) => {
          mockFn.mockImplementation(() => Promise.resolve(value));
          return mockFn;
        };
        mockFn.mockReturnValue = (value: any) => {
          mockFn.mockImplementation(() => value);
          return mockFn;
        };
        // 按需添加其他需要的Jest Mock方法,比如mockRejectedValue、mockReset等
        return mockFn;
      }
    } as any;
    

方案2:用Jest启动服务并保持运行(快速验证)

如果不想修改现有Mock代码,可以让Jest加载所有Mock后启动服务,而非执行测试:

  1. 创建空测试文件start-server.test.ts

    // start-server.test.ts
    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './src/app.module';
    
    let app: any;
    
    beforeAll(async () => {
      app = await NestFactory.create(AppModule);
      await app.listen(3000);
      console.log('NestJS server running on http://localhost:3000');
      // 阻止Jest自动退出
      await new Promise(() => {});
    });
    
    // 空测试用例,避免Jest报错
    test('keep server alive', () => {});
    
  2. 执行命令启动服务

    jest start-server.test.ts --runInBand
    

    此时Jest会加载所有Mock配置,启动服务并保持运行,你可以正常进行外部API调用或漏洞扫描。

验证方式

启动服务后,用curl或Postman调用API,确认返回Mock数据且无外部依赖请求:

curl http://localhost:3000/api/data

返回结果应为你定义的Mock内容,而非真实外部服务的数据。

内容的提问来源于stack exchange,提问作者pharindoko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:05:26