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

如何Mock @aws-sdk/s3-request-presigner中的getSignedUrl函数?

Sinon Stub 无法Mock @aws-sdk/s3-request-presigner 的解决方法

你编写的单元测试中,Sinon Stub 并未生效,调用getPresignedUrl后仍然返回真实的S3预签名URL,而非预设的http://fake-url.com。

原因分析

Node.js模块系统会缓存已加载的模块,你在测试文件中Stub的是测试代码里引用的@aws-sdk/s3-request-presigner实例,而业务代码(定义getPresignedUrl的文件)在测试运行前就已经加载了自己的模块实例,Stub无法影响到这个已加载的实例。

解决方案

使用proxyquire库替换业务代码中的@aws-sdk/s3-request-presigner依赖,确保Stub能覆盖到业务代码实际调用的方法。

步骤1:安装proxyquire

npm install proxyquire --save-dev

步骤2:修改测试代码

const sinon = require('sinon');
const expect = require('chai').expect;
const proxyquire = require('proxyquire');

describe('Tests getPresignedUrl API', () => {
  let getPresignedUrl;
  let getSignedUrlStub;

  beforeEach(() => {
    // 创建Stub并预设返回值
    getSignedUrlStub = sinon.stub().resolves('http://fake-url.com');
    
    // 用proxyquire加载业务模块,替换指定依赖
    getPresignedUrl = proxyquire('./path-to-your-business-module', {
      '@aws-sdk/s3-request-presigner': {
        getSignedUrl: getSignedUrlStub
      }
    }).getPresignedUrl; // 替换为你业务模块导出`getPresignedUrl`的实际方式
  });

  it('should return the mocked presigned URL', async () => {
    const response = await getPresignedUrl('IMG75411705302487970.jpg', 'putObject');
    
    expect(response).to.equal('http://fake-url.com');
    // 可选:验证Stub确实被调用过
    sinon.assert.calledOnce(getSignedUrlStub);
  });
});

额外注意事项

  • 替换./path-to-your-business-module为实际的业务模块文件路径(比如../src/utils/s3.js)。
  • 如果业务模块是默认导出getPresignedUrl,则将.getPresignedUrl改为.default。
  • 若还需要MockS3Client或getCommand函数,可通过proxyquire一并替换,确保测试完全隔离外部依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:57:21