使用Jest测试Node API遇超时错误,求排查原因与修复方案
排查Jest测试Node API超时问题的方案
咱们一步步拆解你遇到的超时错误,下面是关键问题点和对应的修复方法:
1. 修正Express中间件的错误配置
你的测试文件user.test.js里,express.json少了调用括号,这会导致请求体解析中间件无法正常加载,路由处理因无法获取请求数据而卡住:
// 错误写法 app.use(express.json); // 正确写法 app.use(express.json());
2. 延长Jest的超时时间
默认Jest的测试超时阈值是5000ms,数据库操作和API请求的耗时很容易超过这个时间。你可以全局设置超时,或者给单个测试用例单独配置:
// 全局设置(放在describe代码块外) jest.setTimeout(10000); // 调整为10秒 describe("Testing of user route", () => { // 也可以给单个测试用例设置超时 test("should be able to register", () => { // ...测试代码 }, 10000); });
3. 处理数据库连接的资源泄漏
报错提示“improper teardown”,说明测试结束后数据库连接没有正确断开,导致进程无法正常退出。你需要在测试前后管理数据库连接:
// 在测试文件中添加数据库连接管理逻辑 const mongoose = require("mongoose"); beforeAll(async () => { // 建议使用测试专用数据库,避免污染开发环境的数据 await mongoose.connect("mongodb://localhost:27017/MERO-HARDWARE-PASAL-TEST", { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true, }); }); afterAll(async () => { await mongoose.connection.close(); });
同时检查test/config.js里的数据库断开逻辑,确保没有重复连接/断开的冲突。
4. 给测试添加断言,明确测试结束时机
当前你的测试只有console.log,没有任何断言逻辑,Jest无法判断异步请求是否完成,这也是超时的常见诱因。你可以根据业务预期添加断言:
test("should be able to register", async () => { const res = await request(app) .post("/api/signup") // 注意路径是/api/signup,和路由挂载的前缀对应 .send({ name: "testing", email: "testing@gmail.com", password: "testing@123", // 建议不要用邮箱作为密码,避免业务校验失败 }); console.log(res.body); // 添加断言示例 expect(res.statusCode).toBe(201); // 注册成功通常返回201状态码 expect(res.body).toHaveProperty("_id"); // 假设注册成功会返回用户ID });
5. 检查signup控制器的业务逻辑
确保你的signup控制器里的异步操作都正确使用了await,并且在逻辑完成后发送了响应,避免请求挂起:
// 示例signup控制器的正确写法 async function signup(req, res) { try { const user = await User.create(req.body); res.status(201).json(user); // 成功时返回响应 } catch (err) { res.status(400).json({ error: err.message }); // 错误时也必须返回响应 } }
如果控制器没有发送响应,请求会一直处于挂起状态,最终触发超时。
最后验证
修改完成后,你可以用jest --runInBand --detectOpenHandles命令运行测试,这个命令会帮你检测未关闭的资源句柄,进一步排查潜在的泄漏问题。
内容的提问来源于stack exchange,提问作者pujan
相关产品推荐
相关产品推荐

