Home > Back-end >  TypeError: AWS.SecretsManager is not a constructor in unit testing with proxyquire
TypeError: AWS.SecretsManager is not a constructor in unit testing with proxyquire

Time:10-29

I have written a test code to test code that gives credentials from AWS Secret Manager. I used proxyquire and sinon for stubbing and getting this error.

Function I want to test

    exports.getCredsFromAWSSecretsManager = (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;
    });
};

Test case that I have written

const sinon = require("sinon");
const proxyquire = require("proxyquire").noCallThru().noPreserveCache();
const { mockLogger } = require("../../mockdata/mockLogger");

let awsHelper;
let secretsManagerStub;

describe.only("AWS Helper ", () => {

    // function1

    describe("AWS Helper: getCredsFromAWSSecretsManagera method", () => {

        before((done) => {
            const data = {
                SecretString: JSON.stringify({ publicKey: 'secretUsername', privateKey: 'secretPassword' }),
              };
            
            secretsManagerStub = {
                getSecretValue: sinon.stub().callsFake((params, callback) => {
                  callback(null, data);
                }),
               
              };

            const awsStub = {
                
                  SecretsManager: sinon.stub().returns(secretsManagerStub)
               
                
            } 
            awsHelper = proxyquire('../../../utils/aws_helper.js', {
                'aws-sdk':{
                    AWS:awsStub
                } ,
                 "../../utils/logger": mockLogger,
            }); 
            
              

            done();
        });

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

        it('should write random data!', async () => {

            const expectedData = "abcdef";

            secretsManagerStub.getSecretValue.yields(null, expectedData);

            const data = await awsHelper.getCredsFromAWSSecretsManager();

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

    });
});

This code gives me the error saying TypeError: AWS.SecretsManager is not a constructor

any help would be greatly appreciated.

CodePudding user response:

AWS is a namespace, it contains all AWS service classes like SecretsManager. You should provide the awsStub to aws-sdk, there is no need to wrap the awsStub inside an object.

aws_helper.js:

const AWS = require('aws-sdk');

exports.getCredsFromAWSSecretsManager = () => {
  const SM = new AWS.SecretsManager({
    apiVersion: process.env.AWS_SM_API_VERSION,
    region: process.env.AWS_SM_REGION,
  });
  const params = {
    SecretId: '1',
  };

  return SM.getSecretValue(params)
    .promise()
    .then((data) => {
      console.info(data);
      return JSON.parse(data.SecretString);
    })
    .catch((err) => {
      console.error(err);
      throw err;
    });
};

aws_helper.test.js:

const sinon = require('sinon');
const proxyquire = require('proxyquire').noCallThru().noPreserveCache();

let awsHelper;
let secretsManagerStub;

describe('AWS Helper: getCredsFromAWSSecretsManagera method', () => {
  before(() => {
    const data = {
      SecretString: JSON.stringify({ publicKey: 'secretUsername', privateKey: 'secretPassword' }),
    };

    secretsManagerStub = {
      getSecretValue: sinon.stub().returnsThis(),
      promise: sinon.stub().resolves(data),
    };

    const awsStub = {
      SecretsManager: sinon.stub().returns(secretsManagerStub),
    };
    awsHelper = proxyquire('./aws_helper.js', {
      'aws-sdk': awsStub,
    });
  });

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

  it('should write random data!', async () => {
    const data = await awsHelper.getCredsFromAWSSecretsManager();
    sinon.assert.callCount(secretsManagerStub.getSecretValue, 1);
    sinon.assert.match(data, { publicKey: 'secretUsername', privateKey: 'secretPassword' });
  });
});

test result:

  AWS Helper: getCredsFromAWSSecretsManagera method
{
  SecretString: '{"publicKey":"secretUsername","privateKey":"secretPassword"}'
}
    ✓ should write random data!


  1 passing (2s)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |   77.78 |      100 |   66.67 |   77.78 |                   
 aws_helper.js |   77.78 |      100 |   66.67 |   77.78 | 19-20             
---------------|---------|----------|---------|---------|-------------------
  • Related