Issue
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
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.
Here is an 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'
});
Update May 6th, 2023
Since version 3.188.0 (Oct 22), the S3 client supports util functions to consume and parse the response streams.
So now, to mock the response, we need to wrap it with the util function sdkStreamMixin()
from @aws-sdk/util-stream-node
Update Jan 28th, 2024
As mentioned by @Matthew Woo, the @aws-sdk/util-stream-node
package is deprecated and we should use the sdkStreamMixin()
function from @smithy/util-stream
instead
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 ,
});
Answered By - akmalmzamri
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.