如何使用 v3 sdk 通过 jest 模拟 AWS S3 GetObjectCommand?

Int*_*ted 14 amazon-s3 amazon-web-services typescript aws-sdk-js ts-jest

测试 s3 上传?测试的方法是

export class ProcessData {
  constructor() {}

  async process(): Promise<void> {
     const data = await s3Client.send(new GetObjectCommand(bucket));
     await parseCsvData(data.Body)
}
Run Code Online (Sandbox Code Playgroud)

这是我对测试用例的尝试。

import {S3Client} from '@aws-sdk/client-s3';
jest.mock("aws-sdk/clients/s3", () => {
  return {
    S3Client: jest.fn(() => {
        send: jest.fn().mockImplementation(() => {
            data:  Buffer.from(require("fs").readFileSync(path.resolve(__dirname, "test.csv")));
        })
    })
  }
});

describe("@aws-sdk/client-s3 mock", () => {
  test('CSV Happy path', async () => {
    const processData = new ProcessData()
    await processData.process()
  }
}
Run Code Online (Sandbox Code Playgroud)

该进程进入解析方法并抛出错误“您尝试访问的存储桶必须使用特定端点进行寻址”

akm*_*991 21

对于任何想要直接模拟客户端的人,您可以使用AWS SDK 团队推荐的库aws-sdk-client-mock 。

这是一个入门教程

初始步骤:

import fs from 'fs';

import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { mockClient } from 'aws-sdk-client-mock';

const mockS3Client = mockClient(S3Client);
Run Code Online (Sandbox Code Playgroud)

然后你可以这样嘲笑它

mockS3Client.on(GetObjectCommand).resolves({
  Body: fs.createReadStream('path/to/some/file.csv'),
});
Run Code Online (Sandbox Code Playgroud)

您还可以监视客户端

const s3GetObjectStub = mockS3Client.commandCalls(GetObjectCommand)

// s3GetObjectStub[0] here refers to the first call of GetObjectCommand
expect(s3GetObjectStub[0].args[0].input).toEqual({
  Bucket: 'foo', 
  Key: 'path/to/file.csv'
});
Run Code Online (Sandbox Code Playgroud)

2023 年 5 月 6 日更新

从版本3.188.0(10 月 22 日)开始,S3 客户端支持 util 函数来使用和解析响应流。

所以现在,为了模拟响应,我们需要用 util 函数包装sdkStreamMixin()@aws-sdk/util-stream-node

2024 年 1 月 28 日更新

正如 @Matthew Woo 所提到的,该@aws-sdk/util-stream-node包已被弃用,我们应该使用来自sdkStreamMixin()的函数@smithy/util-stream

import fs from 'fs';

import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import {sdkStreamMixin} from '@smithy/util-stream';
import { mockClient } from 'aws-sdk-client-mock';

const mockS3Client = mockClient(S3Client);
const stream = sdkStreamMixin(fs.createReadStream('path/to/some/file.csv'))

mockS3Client.on(GetObjectCommand).resolves({
  Body: stream ,
});
Run Code Online (Sandbox Code Playgroud)

  • NPM JS 网站提到 `@aws-sdk/util-stream-node` 包已被弃用,我们应该使用 `@smithy/util-stream-node` https://www.npmjs.com/package/@aws -sdk/util-stream-node (2认同)