Express控制器单元测试触发Jest 5000ms超时错误求解
问题原因
你遇到的Jest超时由两个核心错误导致:
- Mock的Response对象缺失方法:你的控制器逻辑中成功/失败分支都调用了
res.send()返回响应,但测试代码里的mockResponse仅定义了json和status的mock实现,没有send方法,导致异步函数执行到此处时卡住无法完成。 - Spy未生效:你在测试文件中单独实例化了
employeeService,并对这个实例的getEmployee方法做了mock,但控制器文件内是自己独立实例化了empServices对象,两者不是同一个实例,你的mock完全没有覆盖控制器实际调用的service方法,若真实service方法调用了数据库/外部接口无返回,就会触发超时。
修复方案
1. 补全Mock Response的方法
在mockResponse中添加send的mock实现:
const mockResponse: any = { json: jest.fn(), status: jest.fn(), send: jest.fn() // 新增send方法mock };
2. 正确mock Service类,确保控制器使用被mock的实例
在测试文件顶部先Mock整个employee._service模块,再配置实例方法的返回值:
// 测试文件顶部先mock整个service类 jest.mock('../employee._service'); // 测试用例内的spy修改为: const spy = jest.spyOn(employeeService.prototype, 'getEmployee').mockResolvedValueOnce([]);
3. 可选:调整单测超时时间(非必须,仅当接口逻辑本身耗时较长时添加)
可以在it的第二个参数后增加超时配置,比如设置为10秒:
it("should return pong message", async () => { // 测试逻辑 }, 10000);
修改后完整测试代码
import { Request, Response, NextFunction } from 'express'; import { employeeController } from '../employee.controller'; import { employeeService } from '../employee._service'; // 全局mock整个service类 jest.mock('../employee._service'); describe("employeeController getEmployee 测试", () => { it("应该返回正确的员工列表", async () => { const mockRequest: any = { body: jest.fn(), params: jest.fn() }; const mockResponse: any = { json: jest.fn(), status: jest.fn(), send: jest.fn() }; const mockNext: NextFunction = jest.fn(); // 对类原型的方法做mock,覆盖所有实例的getEmployee调用 const spy = jest.spyOn(employeeService.prototype, 'getEmployee').mockResolvedValueOnce([]); const comments = await employeeController.getEmployee(mockRequest, mockResponse, mockNext); expect(comments).toEqual([]); expect(spy).toHaveBeenCalledWith() expect(spy).toHaveBeenCalledTimes(1) // 可以额外断言res.send被正确调用 expect(mockResponse.send).toHaveBeenCalledWith([]) }); });
内容的提问来源于stack exchange,提问作者Rahil
相关产品推荐
相关产品推荐

