如何在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,重构为独立的模拟模块,在启动服务时手动引入替换:
提取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对象。在启动脚本中手动替换依赖
在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();为非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后启动服务,而非执行测试:
创建空测试文件
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', () => {});执行命令启动服务
jest start-server.test.ts --runInBand此时Jest会加载所有Mock配置,启动服务并保持运行,你可以正常进行外部API调用或漏洞扫描。
验证方式
启动服务后,用curl或Postman调用API,确认返回Mock数据且无外部依赖请求:
curl http://localhost:3000/api/data
返回结果应为你定义的Mock内容,而非真实外部服务的数据。
内容的提问来源于stack exchange,提问作者pharindoko
相关产品推荐
相关产品推荐

