You need to enable JavaScript to run this app. 使用Jest单元测试Lambda函数时如何直接获取uploadToS3返回值
优惠活动
大模型
产品
解决方案
定价
更多

使用Jest单元测试Lambda函数时如何直接获取uploadToS3返回值

解决方案

你可以通过以下两种常用方案实现需求,两种方案都不需要修改生产环境下handler的返回逻辑,完全可以保留给步骤函数用的业务payload结构。


方案1:单独导出uploadToS3函数做单元测试

只需在Lambda源码中新增一行导出逻辑,不影响原有生产逻辑:

// app.js 末尾新增导出
exports.uploadToS3 = uploadToS3;

测试代码可以分别验证上传逻辑和handler返回的业务数据:

const S3Upload = require('../../app');
const AWS = require('aws-sdk')
const s3 = new AWS.S3()

let cat1 = {
  name : 'Bertie',
  breed : 'Cymric',
  color : 'white'
}

jest.mock('aws-sdk', () => {
  const putObjectOutputMock = {
    promise: jest.fn(),
  };
  const putObjectMock = jest.fn(() => putObjectOutputMock);
  const mS3 = {
    putObject: putObjectMock,
  };
  return { S3: jest.fn(() => mS3) };
});

describe('S3 upload test', () => {
  // 单独验证uploadToS3的执行结果
  it('uploadToS3 should return correct s3 response', async () => {
    const mPutObjectResponse = {
      ETag: '"test-etag"',
      ServerSideEncryption: 'AES256'
    };
    s3.putObject().promise.mockResolvedValueOnce(mPutObjectResponse);
    const mEvent = { queryStringParameters: { value: 'test' } };
    // 直接拿到uploadToS3的返回值做断言
    const uploadRes = await S3Upload.uploadToS3(mEvent);
    expect(uploadRes).toEqual(mPutObjectResponse);
    // 验证S3调用参数正确
    expect(s3.putObject).toBeCalledWith({
      Bucket: 'myBucket',
      Key: 'myKey',
      Body: JSON.stringify(cat1),
      ServerSideEncryption: "AES256",
      Tagging: 'myTags'
    });
  })

  // 验证handler返回的业务payload符合预期
  it('lambdaHandler should return correct business data', async () => {
    const mEvent = { queryStringParameters: { value: 'test' }, body: { newStuff: 'stuff goes here', eventList: [] } };
    const returnValue = await S3Upload.lambdaHandler(mEvent);
    // 这里只断言你实际需要返回的业务字段即可
    expect(returnValue).toEqual({
      name: '预期的name值',
      age: '预期的age值'
    });
  })
})

方案2:通过jest.spyOn劫持方法调用(无需对外暴露内部函数)

如果不想把内部的uploadToS3函数对外导出,可以调整handler内的调用方式,让jest可以拦截到方法调用:

// app.js 中将uploadToS3的调用改为从exports对象上取
const upload = await exports.uploadToS3(event);

测试时直接监听方法调用即可拿到返回结果:

it('should get uploadToS3 result without export', async () => {
  // 监听uploadToS3调用
  const uploadSpy = jest.spyOn(S3Upload, 'uploadToS3').mockResolvedValue({
    ETag: '"mock-etag"',
    ServerSideEncryption: 'AES256'
  });
  const mEvent = { queryStringParameters: { value: 'test' } };
  const handlerRes = await S3Upload.lambdaHandler(mEvent);
  // 直接获取uploadToS3的返回值
  const uploadResult = await uploadSpy.mock.results[0].value;
  expect(uploadResult.ETag).toBe('"mock-etag"');
  // 验证handler返回的业务数据
  expect(handlerRes).toEqual({
    name: '预期的name值',
    age: '预期的age值'
  });
  uploadSpy.mockRestore();
})

内容的提问来源于stack exchange,提问作者MountainBiker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 21:36:08