'How do I mock AWS S3 GetObjectCommand with jest using the v3 sdk?

Testing an s3 upload? The method to test is

export class ProcessData {
  constructor() {}

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

This is my attempt at the test case.

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()
  }
}

The process gets to the parse method and throws an error "The bucket you are attempting to access must be addressed using the specific endpoint"



Solution 1:[1]

Applying the example worked https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javascriptv3/example_code/s3/tests/s3_putbucketpolicy.test.js

import {s3Client} from '../clients/s3Client';
jest.mock("../clients/s3Client.ts");

describe("@aws-sdk/client-s3 mock", () => {
  test('CSV Happy path', async () => {
    // @ts-ignore
    s3Client.send.mockResolvedValue({
        Body: Buffer.from(require("fs").readFileSync(path.resolve(__dirname, "nrl-small2.csv")))
    })
 })

Solution 2:[2]

For anyone who wants to mock the client directly, you can use the library aws-sdk-client-mock which is recommended by the AWS SDK team.

Some introductory tutorial

The initial steps:

import fs from 'fs';

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

const mockS3Client = mockClient(S3Client);

And then you can mock it this way

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

You can also spy on the client

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'
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2