TypeError:AWS.SecretsManager 不是使用 proxyquire 进行单元测试的构造函数
Posted
技术标签:
【中文标题】TypeError:AWS.SecretsManager 不是使用 proxyquire 进行单元测试的构造函数【英文标题】:TypeError: AWS.SecretsManager is not a constructor in unit testing with proxyquire 【发布时间】:2021-12-14 04:48:55 【问题描述】:我编写了一个测试代码来测试从 AWS Secret Manager 提供凭证的代码。我使用 proxyquire 和 sinon 来存根并得到这个错误。
我要测试的函数
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;
);
;
我写的测试用例
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);
);
);
);
这段代码给了我错误信息 TypeError:AWS.SecretsManager 不是构造函数
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:AWS
是一个命名空间,它包含所有 AWS 服务类,例如 SecretsManager
。您应该将awsStub
提供给aws-sdk
,无需将awsStub
包装在对象中。
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' );
);
);
测试结果:
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
---------------|---------|----------|---------|---------|-------------------
【讨论】:
非常感谢。现在可以了。我能知道我们为什么要在函数内部定义参数吗?有什么办法不改变功能代码。对不起,我不擅长 AWS 服务 @SanjanaEkanayakeparams
?我没有从您的代码中看到此变量,因此我创建了一个以使代码可执行。重点是演示测试以上是关于TypeError:AWS.SecretsManager 不是使用 proxyquire 进行单元测试的构造函数的主要内容,如果未能解决你的问题,请参考以下文章
反应本机获取多标记[未处理的承诺拒绝:TypeError:TypeError:未定义不是对象(评估'this.state.markers.map
Django TypeError - TypeError: issubclass() arg 1 必须是一个类
pyspark:TypeError:'float'对象不可迭代
Python 3.8 TypeError: can't concat str to bytes - TypeError: a bytes-like object is required, not 's