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

如何用aws-sdk-client-mock编写S3上传测试?返回值为undefined的问题

问题分析与修复方案

核心问题拆解

  1. 测试与服务的Upload实例不关联:你在测试代码里单独创建的Upload对象,和s3Service.uploadObject内部生成的Upload完全是两个独立实例,测试里对这个实例的操作(比如await s3Upload.done())根本不会影响服务方法的返回值。
  2. 断言逻辑错误:s3Upload.on('httpUploadProgress')的返回值是Upload实例本身,不是上传完成后的结果,拿这个和服务返回值做断言本身逻辑就不成立。
  3. Mock不完整+Client实例不共享:你只Mock了CreateMultipartUploadCommand和UploadPartCommand,但分片上传最后需要CompleteMultipartUploadCommand才能完成;另外如果服务内部的Upload用了新创建的S3Client,而非你传入的被Mock的实例,会导致Mock不生效,进而done()返回异常或undefined。

修复步骤

1. 确保服务使用传入的S3Client

修改S3FilesService的uploadObject方法,让内部Upload实例复用构造函数传入的客户端,避免创建新实例导致Mock失效:

class S3FilesService {
  constructor(s3Client, bucket) {
    this.s3Client = s3Client;
    this.bucket = bucket;
  }

  async uploadObject(key, body) {
    const s3Upload = new Upload({
      client: this.s3Client, // 复用传入的被Mock的Client
      params: {
        Bucket: this.bucket,
        Key: key,
        Body: body,
      },
    });
    return await s3Upload.done(); // 确保这里没有遗漏return
  }
}

2. 修正测试代码逻辑

移除测试中多余的Upload实例,专注于验证服务方法的返回值,并补全必要的Mock:

it('should upload files', async () => {
  const s3Mock = mockClient(S3Client);
  const s3 = new S3Client({});
  const s3Service = new S3FilesService(s3, 'test-bucket');

  // 补全分片上传全流程的Mock
  s3Mock.on(CreateMultipartUploadCommand).resolves({ UploadId: '1' });
  s3Mock.on(UploadPartCommand).resolves({ ETag: '1' });
  s3Mock.on(CompleteMultipartUploadCommand).resolves({
    Location: 'https://test-bucket.s3.amazonaws.com/test',
    Bucket: 'test-bucket',
    Key: 'test',
    ETag: '"abc123"'
  });

  // 调用服务上传方法
  const putObjectResult = await s3Service.uploadObject(
    'test',
    'test'
  );

  // 断言返回结果符合预期
  expect(putObjectResult).toEqual({
    Location: 'https://test-bucket.s3.amazonaws.com/test',
    Bucket: 'test-bucket',
    Key: 'test',
    ETag: '"abc123"'
  });

  // 可选:验证Mock命令的调用次数,确保流程正确执行
  expect(s3Mock.commandCalls(CreateMultipartUploadCommand)).toHaveLength(1);
  expect(s3Mock.commandCalls(UploadPartCommand)).toHaveLength(1);
  expect(s3Mock.commandCalls(CompleteMultipartUploadCommand)).toHaveLength(1);
});

3. 排查undefined的额外检查点

如果修复后仍返回undefined,检查:

  • uploadObject方法是否确实返回了await s3Upload.done(),有没有漏掉return关键字;
  • 控制台是否有未捕获的异常,是否因为Mock不全导致done()抛出异常但未被处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:58:40