You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mocha与Nock重复调用出现超时错误的问题求助

问题解决:Nock二次测试超时排查

问题根源

测试超时的核心原因是业务代码中FormData实例被全局复用,导致第二次请求的请求体与Nock预期不匹配,Nock未拦截到请求,Axios尝试发送真实请求最终超时。

看users.js的关键问题:

const data = new FormData(); // 全局实例,所有saveData调用共用同一个对象
exports.saveData = async (lastName, firstName) => {
  try {
    data.append('lastName', lastName); // 每次调用都往同一个实例追加字段
    data.append('firstName', firstName);
  }
  // ...
}

第一次测试后,data中已经存储了一组lastName=Smith&firstName=John,第二次调用saveData会再追加一组相同字段,导致请求体内容翻倍。而Nock预期的是仅包含一组字段的请求,因此匹配失败,请求未被拦截,最终触发超时。

修复方案

将FormData的创建逻辑移到saveData函数内部,确保每次调用都生成全新的实例:

修改后的users.js:

const axios = require('axios')
const FormData = require('form-data');

exports.saveData = async (lastName, firstName) => {
  const data = new FormData(); // 每次调用新建实例,避免字段累积
  try {
    data.append('lastName', lastName);
    data.append('firstName', firstName);
  } catch (error) {
    throw Error(error);
  }
  const url = 'https://sample.com/users';

  const config = {
    method: 'post',
    url,
    data: data
  };
  try {
    const result = await axios(config);
    return result;
  } catch (error) {
    throw new Error('An Error Occurred');
  }
}

额外优化建议

  1. 修正第二个测试的断言逻辑:当请求返回400时,Axios会进入catch分支并抛出错误,当前测试的expect(result).to.be.an('object')会失败,建议调整为验证错误抛出:
it('verifies unsuccessful response', async () => {
  const scope = nock('https://sample.com').post('/users').reply(400, {});
  await expect(users.saveData('Smith', 'John')).to.be.rejectedWith('An Error Occurred');
  scope.done();
});
  1. 给Nock添加请求体匹配验证,确保请求内容符合预期:
const scope = nock('https://sample.com')
  .post('/users', (body) => {
    return body.includes('lastName=Smith') && body.includes('firstName=John');
  })
  .reply(200, {});

内容的提问来源于stack exchange,提问作者cam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:45:32