有没有办法通过 spyOn for aws S3 bucket 来测试功能?

Is there's a way to spyOn for aws S3 bucket to test funcionality?

在使用 typescript 项目时,我们使用 s3 来保存图像。

s3 操作不是直接从 s3 调用的,而是一个名为 FileService 的服务,它具有处理所有基本操作的基本结构,如下所示:

static getSignedUrlFromS3(info: SignedUrlInfo) {
    try {
      return s3.getSignedUrlPromise(info.operationType, {
        Bucket: info.bucket,
        Key: info.key,
        Expires: info.expires,
      });
    } catch (error) {
      winston.error(
        `Error retrieving signed url '${info.key}' from S3 Bucket '${info.bucket}'`,
        error,
      );

      return Promise.resolve();
    }
  }

  /**
   * Get a list of objects from a S3 bucket.
   */
  static getBucketObjectsList(info: ObjectListInfo) {
    try {
      return s3
        .listObjectsV2({
          Bucket: info.bucket,
          Delimiter: info.delimiter,
          Prefix: info.prefix,
        })
        .promise();
    } catch (error) {
      winston.error(
        `Error retrieving object list from S3 Bucket '${info.bucket}'`,
        error,
      );

      return Promise.resolve();
    }

  /**
   * Creates a S3 Presigned Post that for add an object into S3 bucket
   */
  static createS3PresignedPost(info: PresignedUrlInfo) {
    try {
      const params = {
        Bucket: info.bucket,
        Fields: {
          key: info.key,
        },
        Expires: info.expires,
      };

      return s3.createPresignedPost(params);
    } catch (error) {
      winston.error(
        `Error creating presigned POST for S3 Bucket '${info.bucket}'`,
        error,
      );

      return;
    }
  }

所以基本上我有另一个服务使用这个调用另一个服务的特定方法如下:

static getOne(key: string): Promise<Response> {
    return new Promise(async (resolve, reject) => {
      const signedUrl = await FileService.getSignedUrlFromS3({
        bucket: bucketName,
        operationType: 'getObject',
        key: key,
        expires: 60 * 60 * 24,
      });
      if (typeof signedUrl === 'string') {
        resolve({
          key,
          url: signedUrl,
          date: this._getDateFromKey(key),
        });
      } else {
        winston.error(`Error finding ${bucketName}/${key} in S3`);
        reject(new ServerExceptionBadRequest('Unable to get media file.'));
      }
    });
  }

所以我的问题是如何模拟 S3 来模拟服务的功能,例如制作 signedPost GetObject、CopyObject 等

我在文档中看到的是这样的:

jest.mock('@aws-sdk/client-s3');

import { VehicleMediaService } from '@api-services/VehicleMediaService';
import {
  MediaStatus,
  MediaType,
} from '@api-services/VehicleMediaService.interfaces';

import * as S3 from '@aws-sdk/client-s3/S3.spec';

const mocked = S3 as jest.Mocked<typeof S3>;

但不太确定如何使用。非常感谢您的帮助。

解决方案是使用 aws-sdk 模拟服务。 例如:

jest.spyOn(yourService, 'yourMethod').mockImplementation(() => {
      const response = new Response<S3.Types.ListObjectsV2Output, AWSError>();
       
      const result: PromiseResult<S3.Types.ListObjectsV2Output, AWSError> = {
        $response: response,
        Contents: objectFiles,
      };
      return Promise.resolve(result);
    });

这样您就可以模拟任何 aws 服务。