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

使用proxyquire单元测试报错TypeError: AWS.SecretsManager is not a constructor

问题根因
  • proxyquire 注入 aws-sdk 时的导出结构和实际业务代码引用的结构不匹配
  • getSecretValue 桩方法的实现和业务代码的调用方式不兼容

具体原因说明

  1. 导出结构不匹配:正常业务代码中 aws-sdk 的引用方式是 const AWS = require('aws-sdk'),你在 proxyquire 配置里给 aws-sdk 导出的是 { AWS: awsStub },等于业务代码拿到的 AWS 变量外层多套了一层,自然找不到 SecretsManager 构造方法。
  2. 调用方式不兼容:业务代码调用 getSecretValue 后用的是 .promise() 链式调用,你当前的桩方法是按回调模式实现的,没有返回带 promise 方法的对象,后续运行也会报错。
  3. 业务代码存在变量缺失:代码中使用的 params 没有定义,本身就会抛出引用错误。
修复方案

第一步:修复业务代码

补充params变量定义:

exports.getCredsFromAWSSecretsManager = (keyName) => {
    // 补充params定义
    const params = { SecretId: keyName };
    const SM = new AWS.SecretsManager({
        apiVersion: process.env.AWS_SM_API_VERSION,
        region: process.env.AWS_SM_REGION
    });

    return SM.getSecretValue(params).promise().then((data) => {
        logger.info(logMsgs.awsHlpr_smGetSecretValueSuccess(JSON.stringify(data)));
        return JSON.parse(data.SecretString);
        
    }).catch((err) => {
        logger.error(logMsgs.awsHlpr_smGetSecretValueErr(JSON.stringify(err)));
        throw err;
    });
};

第二步:修改测试代码

调整proxyquire注入逻辑和桩方法实现:

const sinon = require("sinon");
const proxyquire = require("proxyquire").noCallThru().noPreserveCache();
const { mockLogger } = require("../../mockdata/mockLogger");
const assert = require('assert'); // 缺引入的话记得补充

let awsHelper;
let secretsManagerStub;

describe.only("AWS Helper ", () => {
  describe("AWS Helper: getCredsFromAWSSecretsManagera method", () => {
    before((done) => {
      const data = {
        SecretString: JSON.stringify({ publicKey: 'secretUsername', privateKey: 'secretPassword' }),
      };
      
      secretsManagerStub = {
        // 适配.promise()调用的桩方法
        getSecretValue: sinon.stub().returns({
          promise: sinon.stub().resolves(data)
        })
      };

      const awsStub = {
        SecretsManager: sinon.stub().returns(secretsManagerStub)
      } 
      // 修复aws-sdk的注入结构,直接导出awsStub
      awsHelper = proxyquire('../../../utils/aws_helper.js', {
        'aws-sdk': awsStub,
        "../../utils/logger": mockLogger,
      }); 
      
      done();
    });

    afterEach(() => {
      sinon.restore();
    });

    it('should return correct secret data', async () => {
      const expectedData = { publicKey: 'secretUsername', privateKey: 'secretPassword' };

      const data = await awsHelper.getCredsFromAWSSecretsManager('test-key');

      sinon.assert.callCount(secretsManagerStub.getSecretValue, 1);
      assert.deepStrictEqual(data, expectedData);
    });
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:48:00