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

如何使用Jest和TypeScript模拟SSM.getParameter的重载签名?

解决AWS SSM getParameter方法模拟的TypeScript类型错误

我正在尝试模拟一个从AWS SSM参数存储获取值的单例类函数,getParameter()的类型定义如下:

getParameter(params: SSM.Types.GetParameterRequest, callback?: (err: AWSError, data: SSM.Types.GetParameterResult) => void): Request<SSM.Types.GetParameterResult, AWSError>;

getParameter(callback?: (err: AWSError, data: SSM.Types.GetParameterResult) => void): Request<SSM.Types.GetParameterResult, AWSError>;

我的测试代码如下:

import {SSM} from 'aws-sdk';
import {SSMParameter} from './src/module/ssm/ssm-cache-parameter';
import {mocked} from 'jest-mock';
import { AWSError } from 'aws-sdk';

jest.mock('aws-sdk', () => {
  const mSSMInstance = {
    getParameter: jest.fn(),
  };
  const mSSM = jest.fn(() => mSSMInstance);

  return { SSM: mSSM };
});


describe('amazon service mock', () => {
  let ssmParameter: SSMParameter;
  it('should get Parameter from Parameter Store', async () => {
    ssmParameter = SSMParameter.getInstance();
    expect(SSM).toBeCalled();
    console.log(ssmParameter);
    const mSSMInstance = new SSM();
    const mData = {
      Parameter: {
        ARN: 'arn:aws:ssm:eu-test-1:123:NAME',
        LastModifiedDate: new Date(2020, 09, 1),
        Name: 'NAME',
        Type: 'String',
        Value: 'VALUE',
        Version: 1,
      }
    };
    const error: AWSError = {
        code: 'ERROR_CODE',
        message: 'ERROR_MESSAGE',
        name: 'ERROR_NAME',
        time: new Date(2020, 09, 1),
    }
    mocked(mSSMInstance.getParameter).mockImplementationOnce(
      (params: SSM.GetParameterRequest, callback?: (err: AWSError, data: SSM.GetParameterResult) => void): any => {
        if (callback) {
          callback(error, mData);
        }
      },
    );
    const actual = ssmParameter.cache({Name: 'NAME', WithDecryption: false}, 30000);
    expect(actual).toBe('VALUE'); 
  });
});

运行测试时遇到以下错误,原因是TypeScript无法匹配getParameter的重载定义:

Argument of type '(params: SSM.GetParameterRequest, callback?: ((err: AWSError, data: SSM.GetParameterResult) => void) | undefined) => any' is not assignable to parameter of type '{ (params: GetParameterRequest, callback?: ((err: AWSError, data: GetParameterResult) => void) | undefined): Request<GetParameterResult, AWSError>; (callback?: ((err: AWSError, data: GetParameterResult) => void) | undefined): Request<...>; }'.
Types of parameters 'params' and 'callback' are incompatible.
Type '((err: AWSError, data: GetParameterResult) => void) | undefined' is not assignable to type 'GetParameterRequest'.
Type 'undefined' is not assignable to type 'GetParameterRequest'.


解决方案

问题出在getParameter有两个重载签名,你的mock实现只匹配了第一个(带params+可选callback),但没有兼容第二个(直接带可选callback)。需要调整mock函数的参数处理逻辑,同时还要返回符合类型要求的Request对象:

修改后的mock实现代码:

mocked(mSSMInstance.getParameter).mockImplementationOnce(
  (param1?: SSM.GetParameterRequest | ((err: AWSError, data: SSM.GetParameterResult) => void), param2?: (err: AWSError, data: SSM.GetParameterResult) => void): any => {
    // 确定回调函数:第一个参数是函数则直接用,否则取第二个参数
    let callback: ((err: AWSError, data: SSM.GetParameterResult) => void) | undefined;
    if (typeof param1 === 'function') {
      callback = param1;
    } else {
      callback = param2;
    }
    // 执行回调
    if (callback) {
      callback(error, mData);
    }
    // 返回空的Request对象以满足类型约束(原方法无论是否传回调都会返回Request)
    return { promise: jest.fn() } as unknown as Request<SSM.Types.GetParameterResult, AWSError>;
  },
);

另外,如果ssmParameter.cache是异步函数,测试中需要使用await并调整断言方式:

const actual = await ssmParameter.cache({Name: 'NAME', WithDecryption: false}, 30000);
expect(actual).toBe('VALUE');

这样就能解决TypeScript的类型不兼容问题,同时正确模拟getParameter的两种调用方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:55:18