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

使用Sinon Stub模拟Axios请求时遇TypeError:无法读取undefined的then属性

问题排查:Sinon Stub模拟Axios两次POST请求失败

下面是你的代码中存在的几个问题及修正方案:

1. 语法错误:response变量定义错误

测试代码里的response用了TypeScript类型注解写法,但当前是JavaScript环境,语法不合法,需要改成赋值语句:

let response = {
  data: {
    url: 'abc'
  }
};

2. 未定义测试依赖变量

测试中的endpoint、id、headers没有提前声明,直接使用会导致ReferenceError,需要在测试块前定义这些变量:

const endpoint = '/test-api';
const id = 'user-123';
const headers = { 'Content-Type': 'application/json' };

3. 第二次Stub返回值不符合函数预期

原函数第二次POST请求的回调里会读取result.data,但你当前Stub返回的是response.data(即{url: 'abc'}),这会导致result.data为undefined,不符合函数逻辑。应该让第二次Stub返回一个包含data属性的完整响应对象:

stubPost.withArgs('abc', id).returns(Promise.resolve({ data: { name: 'test-info' } }));

4. 异步测试未等待Promise完成

getInfo是异步函数,返回Promise,但测试中调用时没加await,会导致测试在Promise执行完成前就结束,进而出现报错或断言失效。必须添加await:

const res = await getInfo(endpoint, headers, id);

5. Sinon Stub的withArgs与onCall混用冲突

同时使用withArgs和onCall时,Sinon的参数匹配逻辑可能出现异常。建议调整Stub的写法,要么按调用次数指定返回值,要么明确匹配参数:

  • 按调用次数Stub(无需严格参数匹配):
stubPost
  .onFirstCall().returns(Promise.resolve(response))
  .onSecondCall().returns(Promise.resolve({ data: { name: 'test-info' } }));
  • 严格匹配参数的写法:
stubPost.withArgs(endpoint, id).returns(Promise.resolve(response));
stubPost.withArgs('abc', id).returns(Promise.resolve({ data: { name: 'test-info' } }));

修正后的完整测试代码

const axios = require('axios').default;
const sinon = require('sinon');
const { getInfo } = require('./index');

describe('To test response', function () {
  let response;
  const endpoint = '/test-api';
  const id = 'user-123';
  const headers = { 'Content-Type': 'application/json' };

  // 每次测试前初始化Stub和response
  beforeEach(function () {
    response = {
      data: {
        url: 'abc'
      }
    };
    sinon.stub(axios, 'post');
  });

  // 每次测试后恢复Axios的post方法,避免污染其他测试
  afterEach(function () {
    axios.post.restore();
  });

  test('success', async function () {
    axios.post
      .withArgs(endpoint, id).returns(Promise.resolve(response))
      .withArgs('abc', id).returns(Promise.resolve({ data: { name: 'test-info' } }));

    const res = await getInfo(endpoint, headers, id);
    // 可以添加断言验证结果是否符合预期
    expect(res).toEqual({ name: 'test-info' });
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:10:33