如何在SuperTest中重复调用API?解决TCPWRAP报错问题
SuperTest重复调用API避免TCPWRAP错误的解决方法
问题根源
你当前的代码在for循环中并行发起10个POST请求,SuperTest会快速创建大量TCP连接,超出系统或服务器的连接上限,从而触发TCPWRAP错误。另外done()在循环结束后立即执行,完全没等待所有请求完成,测试逻辑本身就不严谨。
解决方法
1. 串行执行请求(最稳妥)
利用async/await让请求逐个执行,每次等上一个请求完成后再发起下一个,避免瞬间创建过多TCP连接。Jest/Mocha原生支持async函数作为测试用例,无需使用done回调:
test("Make Some Products (10)", async () => { for (let i = 0; i < 10; i++) { const res = await agent .post(`/api/product`) .send({ ...productJson, title: `${productJson.title}${i}` }) .expect(200); expect(res.body.success).toBeTruthy(); // 注意:这里要取响应返回的实际商品ID,而非固定值 productIds.push(res.body.data.id); } });
2. 控制并发数(平衡速度与连接数)
如果需要更快完成测试,可将请求分批并行执行,限制每批的并发数量,避免连接过载:
test("Make Some Products (10)", async () => { const batchSize = 2; // 每批并发2个请求 const batches = []; // 拆分请求为多个批次 for (let i = 0; i < 10; i += batchSize) { const currentBatch = []; for (let j = i; j < i + batchSize && j < 10; j++) { currentBatch.push( agent .post(`/api/product`) .send({ ...productJson, title: `${productJson.title}${j}` }) .expect(200) .then(res => { expect(res.body.success).toBeTruthy(); productIds.push(res.body.data.id); }) ); } batches.push(currentBatch); } // 按批次执行,每批完成后再执行下一批 for (const batch of batches) { await Promise.all(batch); } });
额外注意点
你原代码中productIds.push(PRODUCT_ID)是错误的,应该从响应体中提取实际生成的商品ID(比如res.body.data.id),否则数组中只会存入固定值,失去测试意义。
内容的提问来源于stack exchange,提问作者DW_Cod
相关产品推荐
相关产品推荐

