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

如何测试AWS SDK v3客户端实例化时传入的参数值?

验证AWS SDK v3客户端实例化的Region参数

问题根源

直接用jest.spyOn替换客户端构造函数会破坏aws-sdk-client-mock的内部拦截逻辑,导致命令匹配失败;而单纯用mockClient无法捕获构造参数。

可行解决方案

方案1:Mock构造函数并保留原逻辑(推荐)

通过jest.mock覆盖客户端构造函数,在记录参数的同时调用原构造函数,确保mockClient能正常拦截命令:

import { EventBridgeClient, DescribeRuleCommand } from "@aws-sdk/client-eventbridge";
import { KMSClient } from "@aws-sdk/client-kms";
import { mockClient } from "aws-sdk-client-mock";
import { YourServiceClass } from "./your-service";

describe("YourServiceClass", () => {
  let ebMock: ReturnType<typeof mockClient>;
  let kmsMock: ReturnType<typeof mockClient>;
  let ebConstructorCalls: any[] = [];
  let kmsConstructorCalls: any[] = [];

  beforeEach(() => {
    // 保存原构造函数
    const originalEbConstructor = EventBridgeClient;
    const originalKmsConstructor = KMSClient;

    // Mock构造函数,记录参数后调用原实现
    jest.mock("@aws-sdk/client-eventbridge", () => ({
      ...jest.requireActual("@aws-sdk/client-eventbridge"),
      EventBridgeClient: jest.fn((opts) => {
        ebConstructorCalls.push(opts);
        return new originalEbConstructor(opts);
      }),
    }));

    jest.mock("@aws-sdk/client-kms", () => ({
      ...jest.requireActual("@aws-sdk/client-kms"),
      KMSClient: jest.fn((opts) => {
        kmsConstructorCalls.push(opts);
        return new originalKmsConstructor(opts);
      }),
    }));

    // 初始化mock客户端
    ebMock = mockClient(EventBridgeClient);
    kmsMock = mockClient(KMSClient);

    // 重置调用记录
    ebConstructorCalls = [];
    kmsConstructorCalls = [];
  });

  afterEach(() => {
    jest.restoreAllMocks();
    ebMock.reset();
    kmsMock.reset();
  });

  test("passes correct region to AWS clients", async () => {
    const testRegion = "us-west-2";
    const service = new YourServiceClass({ region: testRegion });

    // 触发业务方法,实例化客户端
    await service.configureEventBridgeRule();

    // 验证Region参数
    expect(EventBridgeClient).toHaveBeenCalledWith({ region: testRegion });
    expect(KMSClient).toHaveBeenCalledWith({ region: testRegion });

    // 同时验证命令调用(不影响原有测试逻辑)
    expect(ebMock).toHaveReceivedCommandWith(DescribeRuleCommand, { Name: "test-rule-1" });
  });
});

方案2:SpyOn构造函数并保留原实例

如果不想用jest.mock,可以直接SpyOn构造函数,确保返回原实例:

beforeEach(() => {
  ebMock = mockClient(EventBridgeClient);
  kmsMock = mockClient(KMSClient);

  // Spy构造函数,记录参数并返回原实例
  jest.spyOn(EventBridgeClient, "constructor")
    .mockImplementation((opts) => {
      ebConstructorCalls.push(opts);
      return Reflect.construct(EventBridgeClient, [opts]);
    });

  jest.spyOn(KMSClient, "constructor")
    .mockImplementation((opts) => {
      kmsConstructorCalls.push(opts);
      return Reflect.construct(KMSClient, [opts]);
    });
});

关键注意点

  • 必须保留原构造函数的调用逻辑,不能完全替换成空mock,否则aws-sdk-client-mock无法关联实例。
  • 测试完成后要重置mock和调用记录,避免跨测试污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:22:47