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

如何用Jest模拟aws-sdk?仅模拟单个函数的实现方案

如何用Jest仅模拟AWS SDK的单个函数

我来帮你梳理下问题所在,以及如何正确实现你的需求。首先看你当前的代码,主要有两个核心问题:一是没有正确模拟AWS SDK方法的promise()调用,二是断言的对象不对(你要断言的是实例方法,不是类方法)。

问题拆解

你的handler.js里调用了secretsManager.describeSecret().promise()和secretsManager.getSecretValue().promise(),但你之前的mock只返回了空对象,没有包含promise()方法,这会导致代码运行时直接报错。另外,你断言的aws.SecretsManager.getSecretManager不仅拼写错误,而且方向错了——getSecretValue是实例对象的方法,不是SecretsManager类本身的方法。

正确的实现方式

下面是修改后的测试代码,我会一步步解释关键点:

'use strict';
const aws = require('aws-sdk');
const { handler } = require('../../src/rotateSecret/index');
jest.mock('aws-sdk');

// 1. 先创建单独的mock函数,方便后续断言
const mockDescribeSecret = jest.fn().mockReturnThis();
const mockGetSecretValue = jest.fn().mockReturnThis();
const mockPromise = jest.fn();

// 2. 配置SecretsManager的mock构造函数,让new出来的实例包含需要的方法
aws.SecretsManager.mockImplementation(() => ({
  describeSecret: mockDescribeSecret,
  getSecretValue: mockGetSecretValue,
  promise: mockPromise
}));

const event = {
  SecretId: 'test',
  ClientRequestToken: 'ccc',
  Step: 'createSecret',
};

describe('rotateSecret', () => {
  // 3. 每个测试前清空mock的调用记录,避免测试间互相影响
  beforeEach(() => {
    mockDescribeSecret.mockClear();
    mockGetSecretValue.mockClear();
    mockPromise.mockClear();
  });

  it('should not call getSecretValue when conditions are not met', async () => {
    // 4. 模拟describeSecret的返回值,让handler里的someCondition不成立
    // 根据你的业务逻辑调整返回内容,确保代码走到return分支
    mockPromise.mockResolvedValue({ /* 比如返回让someCondition为false的数据,例如:rotationEnabled: false */ });

    await handler(event);

    // 5. 正确断言:describeSecret被调用,getSecretValue没被调用
    expect(mockDescribeSecret).toHaveBeenCalledWith({ SecretId: event.SecretId });
    expect(mockGetSecretValue).not.toHaveBeenCalled();
  });
});

关键说明

  1. 模拟promise调用:AWS SDK的方法返回的是一个Request对象,必须调用.promise()才能获取异步结果,所以我们的mock方法需要返回this(通过mockReturnThis()),保证链式调用能找到promise方法。
  2. 单独管理mock函数:把describeSecret、getSecretValue和promise都做成独立的jest mock函数,这样可以精准控制返回值,也方便后续做调用断言。
  3. 测试隔离:用beforeEach清空mock的调用记录,确保每个测试用例的mock状态都是干净的。
  4. 精准控制业务分支:通过mockPromise.mockResolvedValue()返回特定数据,让代码走到你要测试的分支(也就是不调用getSecretValue的分支)。

如果只想模拟单个函数(其他用真实实现)

如果你的需求是只模拟getSecretValue,而让describeSecret保持真实调用(不推荐,测试应该尽量隔离外部依赖),可以这样调整:

// 创建一个包含真实describeSecret和mock getSecretValue的实例
const mockSecretsManagerInstance = {
  describeSecret: aws.SecretsManager.prototype.describeSecret, // 使用真实方法
  getSecretValue: jest.fn().mockReturnThis(),
  promise: jest.fn().mockResolvedValue({})
};

// 让SecretsManager构造函数返回这个实例
aws.SecretsManager.mockImplementation(() => mockSecretsManagerInstance);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:03:13