I have the following code and unit tests. Its a simple lambda handler function to download a object from S3 bucket. I am unable to successfully write unit tests for it. Need help in debugging.
Handler code
import type { GetObjectCommandInput } from "@aws-sdk/client-s3";
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
import type { S3Event } from "aws-lambda";
async function handler(event: S3Event): Promise<void> {
console.log("Received S3 event:", JSON.stringify(event));
for (const record of event.Records) {
const params: GetObjectCommandInput = {
Bucket: record.s3.bucket.name,
Key: record.s3.object.key,
};
const getObjectCommand = new GetObjectCommand(params);
const s3Data = await s3Client.send(getObjectCommand);
console.log(s3Data);
}
}
Unit test
import { handler } from "~/resources/mons";
import { S3Event } from "aws-lambda";
const mockEvent: S3Event = {
Records: [
{
eventVersion: "2.1",
eventSource: "aws:s3",
awsRegion: "us-east-1",
eventTime: "2024-02-26T16:35:36.549Z",
eventName: "ObjectCreated:Put",
userIdentity: {
principalId: "AWS:AROAW3MD7IRJM6QRM6RCR:abgaura-Isengard",
},
requestParameters: {
sourceIPAddress: "72.21.198.71",
},
responseElements: {
"x-amz-request-id": "0Q0FHDKGYS01M9G0",
"x-amz-id-2":
"D6DaPnYNIw1F3shV+GZY4XdKhxt0hsWlrZf7JC1PIOm3IfrgQsG6Lekf4m1nqIM1RPiTDgUtM2iyzA2o2DwotZTtSYtZEt1H",
},
s3: {
s3SchemaVersion: "1.0",
configurationId: "NTYzOWU1NjQtMjY3Zi00OGNiLTk4ZWItNDljYjY1MjJjMTJl",
bucket: {
name: "santosblueringwebapp-dev-471112565842-us-east-1",
ownerIdentity: {
principalId: "A3UY9USU3LZ6NZ",
},
arn: "arn:aws:s3:::santosblueringwebapp-dev-471112565842-us-east-1",
},
object: {
key: "dist/index.sece.html",
size: 1064,
eTag: "cf1a8087d548591d0328589e075a360d",
versionId: "8UCtubZ8etB_x6v1fdzJKLNffD8gsC0G",
sequencer: "0065DCBDD88107E020",
},
},
},
],
};
describe("Handler", () => {
const mockS3Client = {
send: jest.fn().mockResolvedValue({
/* Mocked response */
}),
};
jest.mock("@aws-sdk/client-s3", () => ({
S3Client: jest.fn(() => mockS3Client),
GetObjectCommand: jest.fn(),
}));
beforeEach(() => {
jest.clearAllMocks();
});
test("retrieves objects from S3 and transforms them to strings", async () => {
await handler(mockEvent);
expect(mockS3Client.send).toHaveBeenCalled();
});
}
The test is failing with this error.
expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
60 | test("retrieves objects from S3 and transforms them to strings", async () => {
61 | await handler(mockEvent);
> 62 | expect(mockS3Client.send).toHaveBeenCalled();
When I use the debugger locally, I see its hitting the send but the test is not able to identify. What am I missing??
I debugged the test code, and noticed that
GetObjectCommandandS3Clientare not mocked. To mock modules, it seemsjest.mock()has to be called at the root of the test module.https://github.com/kentcdodds/how-jest-mocking-works
To pass the test, I made adjustments shown below (look for 4 exclamation marks).
Handler code
Unit test