我 有 一 个 访问 多 个 aws
资源 的 函数 , 现在 需要 测试 这个 函数 , 但是 我 不 知道 如何 模拟 这些 资源 。
我 试 过 跟随 aws-sdk - mock 的 github , 但是 没有 得到 很多 。
function someData(event, configuration, callback) {
// sts set-up
var sts = new AWS.STS(configuration.STS_CONFIG);
sts.assumeRole({
DurationSeconds: 3600,
RoleArn: process.env.CROSS_ACCOUNT_ROLE,
RoleSessionName: configuration.ROLE_NAME
}, function(err, data) {
if (err) {
// an error occurred
console.log(err, err.stack);
} else {
// successful response
// resolving static credential
var creds = new AWS.Credentials({
accessKeyId: data.Credentials.AccessKeyId,
secretAccessKey: data.Credentials.SecretAccessKey,
sessionToken: data.Credentials.SessionToken
});
// Query function
var dynamodb = new AWS.DynamoDB({apiVersion: configuration.API_VERSION, credentials: creds, region: configuration.REGION});
var docClient = new AWS.DynamoDB.DocumentClient({apiVersion: configuration.API_VERSION, region: configuration.REGION, endpoint: configuration.DDB_ENDPOINT, service: dynamodb });
// extract params
var ID = event.queryStringParameters.Id;
console.log('metrics of id ' + ID);
var params = {
TableName: configuration.TABLE_NAME,
ProjectionExpression: configuration.PROJECTION_ATTR,
KeyConditionExpression: '#ID = :ID',
ExpressionAttributeNames: {
'#ID': configuration.ID
},
ExpressionAttributeValues: {
':ID': ID
}
};
queryDynamoDB(params, docClient).then((response) => {
console.log('Params: ' + JSON.stringify(params));
// if the query is Successful
if( typeof(response[0]) !== 'undefined'){
response[0]['Steps'] = process.env.STEPS;
response[0]['PageName'] = process.env.STEPS_NAME;
}
console.log('The response you get', response);
var success = {
statusCode: HTTP_RESPONSE_CONSTANTS.SUCCESS.statusCode,
body: JSON.stringify(response),
headers: {
'Content-Type': 'application/json'
},
isBase64Encoded: false
};
return callback(null, success);
}, (err) => {
// return internal server error
return callback(null, HTTP_RESPONSE_CONSTANTS.BAD_REQUEST);
});
}
});
}
中 的 每 一 个
这 是 我 需要 测试 的 lambda
函数 , 这里 还 使用 了 一些 env 变量 。
现在 我 试 着 用 aws-sdk-mock
为 上面 的 函数 写 单元 测试 , 但是 我 仍然 不 知道 如何 去 做 。 任何 帮助 都 将 不胜 感激 。 下面 是 我 的 测试 代码
describe('test getMetrics', function() {
var expectedOnInvalid = HTTP_RESPONSE_CONSTANTS.BAD_REQUEST;
it('should assume role ', function(done){
var event = {
queryStringParameters : {
Id: '123456'
}
};
AWS.mock('STS', 'assumeRole', 'roleAssumed');
AWS.restore('STS');
AWS.mock('Credentials', 'credentials');
AWS.restore('Credentials');
AWS.mock('DynamoDB.DocumentClient', 'get', 'message');
AWS.mock('DynamoDB', 'describeTable', 'message');
AWS.restore('DynamoDB');
AWS.restore('DynamoDB.DocumentClient');
someData(event, configuration, (err, response) => {
expect(response).to.deep.equal(expectedOnInvalid);
done();
});
});
});
格式
出现 以下 错误 :
{ MultipleValidationErrors: There were 2 validation errors:
* MissingRequiredParameter: Missing required key 'RoleArn' in params
* MissingRequiredParameter: Missing required key 'RoleSessionName' in params
格式
4条答案
按热度按时间vtwuwzda1#
尝试显式设置
aws-sdk
模块。在顶层node_modules项目文件夹中不包含
aws-sdk
的项目结构将不会被正确模拟。例如,在嵌套的项目目录中安装aws-sdk
。您可以通过使用setSDK()
显式设置嵌套aws-sdk
模块的路径来解决此问题。如需了解更多详细信息,请访问:阅读aws-sdk-mock文档,他们已经解释得更好了。
lymgl2op2#
我 强烈 不 同意@ttulka 的 回答 , 所以 我 决定 也 加上 我 自己 的 。
假设 你 在 Lambda 函数 中 收到 了 一 个 事件 , 你 很 可能 会 处理 这个 事件 , 然后 调用 其他 一些 服务 。 它 可能 是 对 S3 、 DynamoDB 、 SQS 、 SNS 、 Kinesis ... ... 你 能 想到 的 。 在 这 一 点 上 有 什么 要 Assert 的 呢 ?
正确 的 论点 !
考虑 以下 事件 :
中 的 每 一 个
现在 , 假设 您 要 调用
documentClient.put
, 并且 要 确保 传递 的 参数 是 正确 的 。格式
对 不 对 ?
现在 , 您 可以 创建 一 个 单元 测试 来 * assert * 正确 的 参数 被 传递 到
documentClient.put
, 这 意味 着 最终 的 对象 应该 如下 所 示 :格式
您 的 测试 必须 Assert
documentClient.put
是 使用 深度 等于 上述 JSON 的 JSON 调用 的 。如果 您 或 任何 其他 开发 人员 现在 出于 某种 原因 删除 了
delete event.additionalInfo
行 , 测试 将 开始 失败 。这 是 非常 强大 的 ! 如果 你 确保 你 的 代码 按照 你 期望 的 方式 工作 , 你 基本 上 根本 不必 担心 创建 集成 测试 。
现在 , 如果 SQS 消费 者 Lambda 期望 消息 的 主体 包含 某 个 字段 , 那么 生产 者 Lambda 应该 总是 处理 它 , 以 确保 正确 的 参数 被 持久 保存 在 Queue 中 。 我 想 现在 你 已经 明白 了 , 对 吧 ?
我 总是 告诉 我 的 同事 , 如果 我们 能 创建 * * * 适当 的 * * * 单元 测试 , 我们 应该 可以 在 95% 的 情况 下 进行 , 而 不 需要 集成 测试 。 当然 , 两者 都 有 更 好 , 但是 考虑 到 创建 集成 测试 ( 如 设置 环境 、 凭据 , 有时 甚至 是 不同 的 帐户 ) 所 花费 的 时间 ,不 值得 。 但 这 只是 我 的 看法 。 欢迎 你 和@ttulka 提出 不同 意见 。
现在 , 回到 你 的 问题 :
您 可以 使用 Sinon 来 模拟 和 Assert Lambda 函数 中 的 参数 。 如果 您 需要 模拟 第 三方 服务 ( 如 DynamoDB 、 SQS 等 ) , 您 可以 创建 一 个 模拟 对象 , 并 使用 Rewire 在 测试 文件 中 替换 它 。 这 通常 是 我 所 走 的 路 , 到 目前 为止 一直 很 好 。
1sbrub3j3#
我认为单元测试是一种检查您的域(业务)规则是否得到满足的方法。
只要您的Lambda只包含AWS服务的集成,为它编写单元测试就没有多大意义。
模拟所有资源意味着,您的测试将只测试这些模拟之间的通信-这样的测试没有任何价值。
外部资源是指输入/输出,这是集成测试所关注的。
编写集成测试并将其作为集成管道的一部分针对真实的部署的资源运行。
qeeaahzv4#
这就是我们在nodeJ中模拟STS的方法。
模拟上述功能