如何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。 - 若还需要Mock
S3Client或getCommand函数,可通过proxyquire一并替换,确保测试完全隔离外部依赖。
内容的提问来源于stack exchange,提问作者Chicky
相关产品推荐
相关产品推荐

