You need to enable JavaScript to run this app. 如何使用Jest正确mock AWS SDK v3的DynamoDBClient实现Node.js Lambda单元测试
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest正确mock AWS SDK v3的DynamoDBClient实现Node.js Lambda单元测试

AWS SDK v3 DynamoDBClient 的 Jest 正确 Mock 方案

原测试代码失效的核心原因

原代码未通过 Jest 的 jest.mock() 机制接管整个 @aws-sdk/client-dynamodb 模块,直接对导入的 DynamoDBClient 类调用 mockImplementation 无实际效果——此时导入的对象还是 SDK 导出的真实客户端类,并非 Jest 生成的可模拟对象,最终实际实例化真实客户端发起网络请求,触发线上资源不存在的报错。

正确实现步骤

  • 在测试文件最顶部声明模块Mock:将 jest.mock 写在所有 require/import 语句之前(Jest 会自动提升 Mock 声明的执行顺序,确保先完成模块模拟再加载业务代码),把 DynamoDBClient 替换为可模拟的 Jest 函数,实例上的 send 方法替换为可自定义的 Jest Mock 函数。
  • 在测试用例中定制Mock返回逻辑:针对每个测试场景,给 send 方法设置对应返回值,同时通过 Mock 函数的断言能力,验证客户端是否收到了正确的调用参数。
  • 在每个测试前重置Mock状态:避免上一个测试场景设置的返回值、调用记录影响后续测试用例的执行结果。

完整可运行的测试代码示例

// 测试文件最开头,所有引入语句之前完成模块Mock
// 定义独立的send mock函数,方便测试中直接调用和断言
const mockDynamoSend = jest.fn()

jest.mock('@aws-sdk/client-dynamodb', () => ({
  DynamoDBClient: jest.fn().mockImplementation(() => ({
    send: mockDynamoSend
  }))
}))

const LambdaTester = require('lambda-tester')
const handler = require('./my-handler').handler

describe('handler', function () {
  // 每个测试前清空所有mock的调用记录和自定义实现,避免交叉污染
  beforeEach(() => {
    jest.clearAllMocks()
  })

  it('Handler should work properly', async function () {
    // 准备DynamoDB返回的模拟响应
    const mockSuccessResponse = {
      Item: {
        a: { S: 'a' },
        b: { S: 'b' }
      }
    }
    // 给send方法设置Promise形式的返回值,匹配真实SDK的异步行为
    mockDynamoSend.mockResolvedValue(mockSuccessResponse)

    await LambdaTester(handler)
      .event({
        // 填入你的测试事件参数
      })
      .expectResult((res) => {
        // 业务结果断言
        // 同时验证DynamoDB客户端被正确调用
        expect(mockDynamoSend).toHaveBeenCalledWith(
          expect.objectContaining({
            input: expect.objectContaining({
              TableName: '你的目标DynamoDB表名'
            })
          })
        )
      })
  })
})

常见注意事项

  • 如果项目中还用到了 @aws-sdk/lib-dynamodb(兼容旧版SDK的DocumentClient能力),按照完全相同的逻辑对该模块做Mock即可,核心思路是对所有引入的AWS SDK模块提前声明Mock,不直接使用真实模块的类。
  • 不要将 jest.mock 写在测试用例内部,否则会因为执行顺序问题导致Mock不生效,最终依然调用真实的SDK方法。
  • 上述写法兼容两种客户端实例化场景:无论Handler是在模块加载时全局实例化DynamoDBClient,还是在每次Lambda调用时临时实例化,Mock逻辑都会正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 10:27:04