我有以下代码和单元测试。它是一个简单的 lambda 处理函数,用于从 S3 存储桶下载对象。我无法成功地为其编写单元测试。需要调试帮助。
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);
}
}
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();
});
}
测试失败并出现此错误。
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();
当我在本地使用调试器时,我看到它命中了发送,但测试无法识别。我错过了什么??
我调试了测试代码,发现
GetObjectCommand
和 S3Client
没有被模拟。要模拟模块,似乎必须在测试模块的根部调用jest.mock()
。
https://github.com/kentcdodds/how-jest-mocking-works
事实证明,如果您在模块的根目录中调用 jest.mock,则模拟将在任何 require 语句解析/运行之前发生。
为了通过测试,我做了如下调整(寻找 4 个感叹号)。
处理程序代码
const s3Client = new S3Client(); // !!!! Added this line
const s3Data = await s3Client.send(getObjectCommand);
单元测试
import { handler } from "~/resources/mons";
import { S3Event } from "aws-lambda";
// !!!!
// Moved module mocking to the root of the test module
// !!!!
const mockS3Client = {
send: jest.fn().mockResolvedValue({
/* Mocked response */
}),
};
jest.mock("@aws-sdk/client-s3", () => ({
S3Client: jest.fn(() => mockS3Client),
GetObjectCommand: jest.fn(),
}));
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", () => {
beforeEach(() => {
jest.clearAllMocks();
});
test("retrieves objects from S3 and transforms them to strings", async () => {
await handler(mockEvent);
expect(mockS3Client.send).toHaveBeenCalled();
});
}); // !!!! Added ");"