You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest模拟AWS Lambda中的lambda.invoke().promise()调用?

在Jest中模拟AWS Lambda的invoke().promise()调用

问题描述

我有一段待测试的单元代码:

import { Lambda } from 'aws-sdk'

export const handler = async (
  event: APIGatewayEvent,
  ctx: Context,
  cb: APIGatewayProxyCallback
): Promise<void> => {
  
  const lambda = new Lambda()
  await lambda.invoke(params).promise()
}

我希望在Jest中模拟其中的await lambda.invoke(params).promise()调用,让它直接resolve或“跳过”,但尝试使用jest.spyOn未成功,请问该如何实现?


解决方案

方法一:直接mock整个AWS SDK的Lambda类

通过jest.mock直接替换aws-sdk模块中的Lambda实现,让它返回预设的mock方法:

// 测试文件
import { handler } from './your-handler-file';
import { Lambda } from 'aws-sdk';

// 模拟aws-sdk的Lambda类
jest.mock('aws-sdk', () => {
  // 模拟invoke方法,链式调用需要返回自身
  const mockInvoke = jest.fn().mockReturnThis();
  // 模拟promise方法,让它直接resolve
  const mockPromise = jest.fn().mockResolvedValue({});

  return {
    Lambda: jest.fn(() => ({
      invoke: mockInvoke,
      promise: mockPromise
    }))
  };
});

describe('handler 单元测试', () => {
  it('应正确模拟lambda.invoke().promise()调用', async () => {
    await handler({}, {} as Context, jest.fn());

    // 验证调用逻辑
    expect(Lambda).toHaveBeenCalled();
    expect(Lambda.mock.instances[0].invoke).toHaveBeenCalled(); // 可添加预期的params参数
    expect(Lambda.mock.instances[0].promise).toHaveBeenCalled();
  });
});

方法二:使用jest.spyOn模拟原型方法

因为代码中是通过new Lambda()创建实例,所以需要Spy Lambda类原型上的方法,而非类本身:

import { handler } from './your-handler-file';
import { Lambda } from 'aws-sdk';

describe('handler 单元测试', () => {
  let invokeSpy: jest.SpyInstance;
  let promiseSpy: jest.SpyInstance;

  beforeEach(() => {
    // 模拟invoke方法,链式调用需返回this
    invokeSpy = jest.spyOn(Lambda.prototype, 'invoke').mockReturnThis();
    // 让promise方法直接resolve
    promiseSpy = jest.spyOn(Lambda.prototype, 'promise').mockResolvedValue({});
  });

  afterEach(() => {
    // 恢复原方法,避免影响其他测试
    invokeSpy.mockRestore();
    promiseSpy.mockRestore();
  });

  it('应正确跳过lambda调用逻辑', async () => {
    await handler({}, {} as Context, jest.fn());

    expect(invokeSpy).toHaveBeenCalled();
    expect(promiseSpy).toHaveBeenCalled();
  });
});

为什么之前的jest.spyOn失败?

大概率是因为你直接Spy了Lambda类而非它的原型对象,或者没有处理链式调用:invoke()需要返回一个带有promise()方法的对象(通过mockReturnThis()实现),否则链式调用会报错,导致mock失效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:41:29