使用Jest和Supertest测试Serverless接口时异常未处理导致测试卡住如何解决
问题根因
Jest无法正常退出、测试卡顿的核心原因是Express async路由函数内抛出的异常没有被正确处理,导致请求一直处于挂起状态,没有返回响应,Supertest持续等待请求完成形成了未终止的异步操作。
排查与解决步骤
- 第一步:修复路由层异常处理逻辑
原代码catch块中直接throw exception,Express默认不会捕获async路由函数内抛出的异常,异常没有被转换为HTTP响应返回,是请求悬停的直接原因。将catch块的抛出逻辑改为返回错误响应即可:
catch (exception) { return res.status(500).json({error: 'Database query failed'}); }
修改后无论接口请求成功还是失败,都会给客户端返回响应,Supertest的请求可以正常结束。
- 第二步:完善测试用例断言
现有测试用例没有对响应结果做校验,补充错误场景的状态码断言即可:
test("should throw error on failing to get user from database", async () => { mockScan.mockImplementation(() => { return { promise() { return Promise.reject({}); }, }; }); const response = await request .post(`/post`) .send(); expect(response.statusCode).toBe(500); });
- 第三步:可选全局兜底方案
如果需要统一处理所有路由的异常,可以在所有路由定义之后添加全局错误处理中间件:
// Express全局错误处理中间件必须包含四个参数err、req、res、next app.use((err, req, res, next) => { console.error('Server error:', err); res.status(500).json({error: 'Internal server error'}); });
该中间件会自动捕获所有路由抛出的异常,统一返回错误响应,避免出现请求悬停的问题。
- 通用排查方法
如果后续还有类似问题,可以给Jest加上--detectOpenHandles参数运行,会输出具体未关闭的异步操作信息,方便快速定位问题。
内容的提问来源于stack exchange,提问作者Rahul Dev
相关产品推荐
相关产品推荐

