我正在尝试通过在本地运行来对JS AWS Lambda进行单元测试。为了模拟Lambda环境,我假设Lambda与AWS.config.credentials具有相同的角色,然后简单地调用我使用require导入的Lambda函数。
如果我将Lambda函数复制并粘贴到测试文件中,但是如果我导入它,那么这个函数似乎运行时干净的AWS.config并没有我的配置。我可以改变Lambda模块导入AWS的方式(使其成为全局或执行其他操作)以便从测试中获取配置,但我更希望保持文件完全符合上传到Lambda的要求。
在AWS Lambda中,AWS凭证以某种方式预先配置,而模块不必执行任何操作,我想模拟该功能。如何在Node中完成?
编辑: 您可以在AWS Lambda中运行任何示例函数。例如,只有以下代码在适当的AWS Lambda中运行时才起作用。
var AWS = require("aws-sdk");
var dynamo = new AWS.DynamoDB.DocumentClient();
dynamo.query(...)

要在本地运行此功能,您必须在此代码之前添加以下内容:
AWS.config.update({region: 'us-east-1'});
AWS.config.credentials = new AWS.SharedIniFileCredentials();
AWS.config.credentials = new AWS.TemporaryCredentials({
RoleArn: 'arn:aws:iam::1234567890:role/TemporaryCredentials',
});

问题是在单元测试文件中运行此配置步骤不会使配置对导入的lambda函数可用,因此不能正确模拟环境。
答案 0 :(得分:1)
在运行测试之前,需要调用STS.AssumeRole并获取临时凭证,并将它们放在环境中。这就是Lambda似乎如何做到这一点。该服务调用AssumeRole,获取临时凭证,并将它们放在SDK期望的位置。
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
如果在正在运行的Lambda函数中检查process.env
,您将看到这些变量已设置。
请注意,在您运行测试之前我说""我的意思是在你开始之前 - 而不是在代码的顶部。
另请注意,访问密钥和密钥不是来自IAM凭据的密钥和密钥。调用AssumeRole为您提供临时密钥,临时密钥和临时令牌。
答案 1 :(得分:1)
这是我使用jest的解决方案。当然,您可以将其适应其他测试框架。我认为jest
更容易。
基本上,您创建了aws-sdk
模块的模拟,该模块返回实际的aws-sdk
模块 AND 您自己的修改。
// __mocks__/aws-sdk.js (Jest automocks this module if you follow this convention)
'use strict';
const AWS = require('AWS');
// Make your own modifications
AWS.config.update({region: 'us-east-1'});
AWS.config.credentials = new AWS.SharedIniFileCredentials();
AWS.config.credentials = new AWS.TemporaryCredentials({
RoleArn: 'arn:aws:iam::1234567890:role/TemporaryCredentials',
});
//export modified module
module.exports = AWS
这样,当你的lambda需要aws-sdk
时,它会加载这个模块。随之而来的是实际的aws-sdk
模块和您的附加配置。
参考:https://facebook.github.io/jest/docs/en/manual-mocks.html#content