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

如何修改jest.mock返回值 模拟aws-sdk SQS接口报错测试场景

问题根因

你当前的逻辑有三个核心问题,导致错误分支无法覆盖:

  • 你写的changeMessageVisibility: jest.fn().mockReturnValue( {} )只是模拟了方法的同步返回值,完全没有执行调用时传入的第二个回调参数,不管成功、失败的回调逻辑都不会触发,自然进不到错误分支。
  • 测试用例里监听的是console.error,但你的业务代码错误分支用的是console.log打印日志,就算回调触发了也会因为监听对象不对导致断言失败。
  • 至于jest.mock写在describe、beforeAll里失效,是Jest本身的机制导致:Jest编译阶段会自动把所有jest.mock调用提升到文件最顶部,写在块级作用域里会因为作用域提升不符合预期导致mock失效,固定把jest.mock写在文件顶部即可。
方案1:直接调整现有mock逻辑支持回调触发

不需要大改业务代码,只要调整mock实现,让它主动执行传入的回调即可。
首先修改顶部的基础mock,默认模拟接口调用成功的场景:

jest.mock('aws-sdk', () => {
  const SQSMocked = {
    // 接收入参,第二个参数就是业务代码传的回调,默认传null作为错误值代表成功
    changeMessageVisibility: jest.fn((params, callback) => callback(null, {})),
  };
  const configMocked = {
    update: jest.fn().mockReturnThis()
  }
  return {
    SQS: jest.fn(() => SQSMocked),
    config: configMocked
  };
});

在测试错误场景的用例里,临时修改mock实现,给回调传入错误对象即可,记得用例执行完还原mock避免影响其他用例:

test("changeMessageVisibility调用失败时会打印错误日志", async () => {
  // 缓存原有mock实现,测完还原
  const originalImpl = sqs.changeMessageVisibility.getMockImplementation();
  // 注意这里要spy console.log,和业务代码保持一致
  const logSpy = jest.spyOn(console, 'log').mockImplementation(() => null);
  const testError = new Error('SQS change visibility timeout failed');
  // 临时模拟接口报错
  sqs.changeMessageVisibility.mockImplementationOnce((params, callback) => {
    callback(testError, null);
  });

  await ingest.retryIngest(TEST_CONSTANTS.sqsIngestEventMessageWithTwoRecords);

  // 断言日志打印逻辑被触发
  expect(logSpy).toHaveBeenCalledTimes(1);
  expect(logSpy).toHaveBeenCalledWith(testError, testError.stack);

  // 清理现场
  logSpy.mockRestore();
  sqs.changeMessageVisibility.mockImplementation(originalImpl);
})
方案2:重构业务代码降低测试成本

AWS SDK原生支持Promise形式的调用,比回调写法更易维护、更好mock,推荐把业务代码改成Promise+async/await的写法:

try {
  await sqs.changeMessageVisibility({
    QueueUrl: sourceQueueURL,
    ReceiptHandle: record.receiptHandle,
    VisibilityTimeout: camera.ingest.retryIntr
  }).promise();
} catch (err) {
  console.log(err, err.stack);
}

重构后mock逻辑更简单,不需要手动处理回调参数,模拟成功就返回resolve的promise,模拟失败就返回rejected的promise即可,错误场景的mock可以简化为:

const testError = new Error('SQS request failed');
sqs.changeMessageVisibility.mockReturnValueOnce({
  promise: jest.fn().mockRejectedValue(testError)
});

这种写法完全规避了回调参数处理的问题,代码可读性也更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:18:16