AWS SAM CLI 单元测试 Lambda 函数 NodeJS
AWS SAM CLI Unit testing Lambda Functions NodeJS
我正在使用 SAM CLI 来测试和部署 AWS Lambda 函数。我正在尝试 运行 在 NodeJS 中使用 Mocha 和 Chai 进行单元测试。测试位于 test
目录中,我可以使用命令 mocha --recursive
.
运行 测试
问题是我在测试中使用了环境变量。我的环境变量在 SAM CLI 的 template.yaml
文件中定义。它看起来像这样:
RefreshFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/index.handler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 100
Environment:
Variables:
APP_ID: A
CLIENT_ID: B
CLIENT_SECRET: C
AWS_REGION_DB: D
它们在此处定义为当我部署我的函数时,它们也会自动将其转移到 AWS 上。它还允许我使用 sam local invoke
命令,该命令使用 Docker.
在本地 运行s 我的 lambda 函数
有没有人知道 sam local invoke
命令可用于 运行 本地测试用例而不是 运行 lambda 函数?或者如何使用 mocha 和 chai 从测试用例中访问 template.yaml
文件中的环境变量?
决定更新此答案,因为有几个人已将此问题添加为书签。
要获得相同的设置,我必须从 运行 sam init
、select AWS Quick Start Templates
开始,运行 时间是 nodejs12.x
并且要使用的应用程序模板是 Quick Start: From Scratch
.
完成此步骤后,您的 sam 应用程序中的目录结构应该如下所示。
-rw-r--r-- 1 user 9596 Apr 9 12:02 README.md
drwxr-xr-x 4 user 4096 Apr 9 12:02 __tests__
-rwxr-xr-x 1 user 828 Apr 9 12:02 buildspec.yml
-rwxr-xr-x 1 user 374 Apr 9 12:02 package.json
drwxr-xr-x 3 user 4096 Apr 9 12:02 src
-rwxr-xr-x 1 user 1545 Apr 9 12:02 template.yml
运行 和 npm install
来安装创建您的 node_modules
目录的依赖项。
完成后 运行 下面的命令安装 dotenv
模块。
npm install dotenv
在根目录中创建一个名为 .env
的文件。您的根目录现在应该如下所示。
-rw-r--r-- 1 user 9596 Apr 9 12:02 README.md
drwxr-xr-x 4 user 4096 Apr 9 12:02 __tests__
-rwxr-xr-x 1 user 828 Apr 9 12:02 buildspec.yml
drwxr-xr-x 391 user 16384 Apr 9 12:05 node_modules
-rw-r--r-- 1 user 488688 Apr 9 12:05 package-lock.json
-rwxr-xr-x 1 user 374 Apr 9 12:02 package.json
drwxr-xr-x 3 user 4096 Apr 9 12:02 src
-rwxr-xr-x 1 user 1545 Apr 9 12:02 template.yml
-rw-r--r-- 1 user 28 Apr 9 11:06 .env
现在在你的 .env
文件中创建一个环境变量,就像我下面的示例一样。
TEST_ENV_VAR=HELLO_FROM_TEST
在您的 template.yml
文件中还定义了一个同名的环境变量,但给它一个不同的值,这样我们就可以看到下一步何时读取两个不同的位置。
helloFromLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/hello-from-lambda.helloFromLambdaHandler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 100
Description: A Lambda function that returns a static string.
Policies:
- AWSLambdaBasicExecutionRole
Environment:
Variables:
TEST_ENV_VAR: Hello_From_Local_Invoke #HERE WE ARE DEFINING ENV VARS
在位于 src/handlers/hello-from-lambda.js
的处理程序文件中,将代码更改为以下读取环境变量 TEST_ENV_VAR
并返回的代码。
exports.helloFromLambdaHandler = async () => {
// Read in the environment variable
const message = process.env.TEST_ENV_VAR
// Log the environment variable out
console.info(`${message}`);
// Return the environment variable so we can verify value in test case
return message;
}
在位于 __tests__/unit/handlers/hello-from-lambda.test.js
的测试处理程序中粘贴以下代码。它从您之前使用 dotenv
模块创建的 .env
中读取环境变量。如果从 helloFromLambdaHandler
返回的值等于值 HELLO_FROM_TEST
,即我们在 .env
文件中为环境变量 TEST_ENV_VAR
定义的值,则测试现在将通过。
// Import all functions from hello-from-lambda.js
const lambda = require('../../../src/handlers/hello-from-lambda.js');
require('dotenv').config(); // HERE WE ARE USING THE dotenv MODULE
// This includes all tests for helloFromLambdaHandler()
describe('Test for hello-from-lambda', function () {
// This test invokes helloFromLambdaHandler() and compare the result
it('Verifies successful response', async () => {
// Invoke helloFromLambdaHandler()
const result = await lambda.helloFromLambdaHandler();
// The expected result should match the return from your Lambda function.
// We expect it to be HELLO_FROM_TEST as thats what is in our .env file for the variable TEST_ENV_VAR
const expectedResult = 'HELLO_FROM_TEST';
// Compare the result with the expected result
expect(result).toEqual(expectedResult);
});
});
现在运行通过运行在根目录中执行npm run test
命令进行测试,它通过表明我们正在从.env
中读取测试用例。
$ npm run test
> replaced-by-user-input@0.0.1 test
> jest --roots __tests__/unit
PASS __tests__/unit/handlers/hello-from-lambda.test.js
Test for hello-from-lambda
✓ Verifies successful response (12 ms)
console.info
HELLO_FROM_TEST
at Object.helloFromLambdaHandler (src/handlers/hello-from-lambda.js:5:13)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.919 s, estimated 1 s
Ran all test suites.
为了证明我们正在从 template.yml
文件中读取生产构建,您可以通过 运行ning sam build
调用本地测试来构建项目,然后 sam local invoke
全部来自根目录。
$ sam local invoke
Invoking src/handlers/hello-from-lambda.helloFromLambdaHandler (nodejs12.x)
Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-nodejs12.x:rapid-1.12.0.
Mounting /home/warren/lambda/new_test/sam-app/.aws-sam/build/helloFromLambdaFunction as /var/task:ro,delegated inside runtime container
START RequestId: 4de19569-5ebc-1c20-1cec-9a290dd3ef9b Version: $LATEST
2021-04-09T11:29:40.993Z 4de19569-5ebc-1c20-1cec-9a290dd3ef9b INFO Hello_From_Local_Invoke
END RequestId: 4de19569-5ebc-1c20-1cec-9a290dd3ef9b
REPORT RequestId: 4de19569-5ebc-1c20-1cec-9a290dd3ef9b Init Duration: 187.97 ms Duration: 6.80 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 48 MB
"Hello_From_Local_Invoke"
你可以看到我们现在得到值 Hello_From_Local_Invoke
,这是我们在 template.yml
文件中分配给环境变量 TEST_ENV_VAR
的值。
希望对您有所帮助!
我找到了另一种方法。您可以在自己的本地机器上设置环境变量:
苹果操作系统:
export APP_ID=A
Windows:
SET APP_ID=A
然后 运行 像往常一样使用 mocha 进行测试。
环境变量应在您的环境中定义。如果您想在本地 运行 但更改环境变量 some/all,则可以使用 dotenv
等其他工具。您也可以将这些放在 scripts
部分的 package.json
和 FOO=BAR
中。只要里面没有秘密就可以安全进行。
我正在使用 SAM CLI 来测试和部署 AWS Lambda 函数。我正在尝试 运行 在 NodeJS 中使用 Mocha 和 Chai 进行单元测试。测试位于 test
目录中,我可以使用命令 mocha --recursive
.
问题是我在测试中使用了环境变量。我的环境变量在 SAM CLI 的 template.yaml
文件中定义。它看起来像这样:
RefreshFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/index.handler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 100
Environment:
Variables:
APP_ID: A
CLIENT_ID: B
CLIENT_SECRET: C
AWS_REGION_DB: D
它们在此处定义为当我部署我的函数时,它们也会自动将其转移到 AWS 上。它还允许我使用 sam local invoke
命令,该命令使用 Docker.
有没有人知道 sam local invoke
命令可用于 运行 本地测试用例而不是 运行 lambda 函数?或者如何使用 mocha 和 chai 从测试用例中访问 template.yaml
文件中的环境变量?
决定更新此答案,因为有几个人已将此问题添加为书签。
要获得相同的设置,我必须从 运行 sam init
、select AWS Quick Start Templates
开始,运行 时间是 nodejs12.x
并且要使用的应用程序模板是 Quick Start: From Scratch
.
完成此步骤后,您的 sam 应用程序中的目录结构应该如下所示。
-rw-r--r-- 1 user 9596 Apr 9 12:02 README.md
drwxr-xr-x 4 user 4096 Apr 9 12:02 __tests__
-rwxr-xr-x 1 user 828 Apr 9 12:02 buildspec.yml
-rwxr-xr-x 1 user 374 Apr 9 12:02 package.json
drwxr-xr-x 3 user 4096 Apr 9 12:02 src
-rwxr-xr-x 1 user 1545 Apr 9 12:02 template.yml
运行 和 npm install
来安装创建您的 node_modules
目录的依赖项。
完成后 运行 下面的命令安装 dotenv
模块。
npm install dotenv
在根目录中创建一个名为 .env
的文件。您的根目录现在应该如下所示。
-rw-r--r-- 1 user 9596 Apr 9 12:02 README.md
drwxr-xr-x 4 user 4096 Apr 9 12:02 __tests__
-rwxr-xr-x 1 user 828 Apr 9 12:02 buildspec.yml
drwxr-xr-x 391 user 16384 Apr 9 12:05 node_modules
-rw-r--r-- 1 user 488688 Apr 9 12:05 package-lock.json
-rwxr-xr-x 1 user 374 Apr 9 12:02 package.json
drwxr-xr-x 3 user 4096 Apr 9 12:02 src
-rwxr-xr-x 1 user 1545 Apr 9 12:02 template.yml
-rw-r--r-- 1 user 28 Apr 9 11:06 .env
现在在你的 .env
文件中创建一个环境变量,就像我下面的示例一样。
TEST_ENV_VAR=HELLO_FROM_TEST
在您的 template.yml
文件中还定义了一个同名的环境变量,但给它一个不同的值,这样我们就可以看到下一步何时读取两个不同的位置。
helloFromLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/hello-from-lambda.helloFromLambdaHandler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 100
Description: A Lambda function that returns a static string.
Policies:
- AWSLambdaBasicExecutionRole
Environment:
Variables:
TEST_ENV_VAR: Hello_From_Local_Invoke #HERE WE ARE DEFINING ENV VARS
在位于 src/handlers/hello-from-lambda.js
的处理程序文件中,将代码更改为以下读取环境变量 TEST_ENV_VAR
并返回的代码。
exports.helloFromLambdaHandler = async () => {
// Read in the environment variable
const message = process.env.TEST_ENV_VAR
// Log the environment variable out
console.info(`${message}`);
// Return the environment variable so we can verify value in test case
return message;
}
在位于 __tests__/unit/handlers/hello-from-lambda.test.js
的测试处理程序中粘贴以下代码。它从您之前使用 dotenv
模块创建的 .env
中读取环境变量。如果从 helloFromLambdaHandler
返回的值等于值 HELLO_FROM_TEST
,即我们在 .env
文件中为环境变量 TEST_ENV_VAR
定义的值,则测试现在将通过。
// Import all functions from hello-from-lambda.js
const lambda = require('../../../src/handlers/hello-from-lambda.js');
require('dotenv').config(); // HERE WE ARE USING THE dotenv MODULE
// This includes all tests for helloFromLambdaHandler()
describe('Test for hello-from-lambda', function () {
// This test invokes helloFromLambdaHandler() and compare the result
it('Verifies successful response', async () => {
// Invoke helloFromLambdaHandler()
const result = await lambda.helloFromLambdaHandler();
// The expected result should match the return from your Lambda function.
// We expect it to be HELLO_FROM_TEST as thats what is in our .env file for the variable TEST_ENV_VAR
const expectedResult = 'HELLO_FROM_TEST';
// Compare the result with the expected result
expect(result).toEqual(expectedResult);
});
});
现在运行通过运行在根目录中执行npm run test
命令进行测试,它通过表明我们正在从.env
中读取测试用例。
$ npm run test
> replaced-by-user-input@0.0.1 test
> jest --roots __tests__/unit
PASS __tests__/unit/handlers/hello-from-lambda.test.js
Test for hello-from-lambda
✓ Verifies successful response (12 ms)
console.info
HELLO_FROM_TEST
at Object.helloFromLambdaHandler (src/handlers/hello-from-lambda.js:5:13)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.919 s, estimated 1 s
Ran all test suites.
为了证明我们正在从 template.yml
文件中读取生产构建,您可以通过 运行ning sam build
调用本地测试来构建项目,然后 sam local invoke
全部来自根目录。
$ sam local invoke
Invoking src/handlers/hello-from-lambda.helloFromLambdaHandler (nodejs12.x)
Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-nodejs12.x:rapid-1.12.0.
Mounting /home/warren/lambda/new_test/sam-app/.aws-sam/build/helloFromLambdaFunction as /var/task:ro,delegated inside runtime container
START RequestId: 4de19569-5ebc-1c20-1cec-9a290dd3ef9b Version: $LATEST
2021-04-09T11:29:40.993Z 4de19569-5ebc-1c20-1cec-9a290dd3ef9b INFO Hello_From_Local_Invoke
END RequestId: 4de19569-5ebc-1c20-1cec-9a290dd3ef9b
REPORT RequestId: 4de19569-5ebc-1c20-1cec-9a290dd3ef9b Init Duration: 187.97 ms Duration: 6.80 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 48 MB
"Hello_From_Local_Invoke"
你可以看到我们现在得到值 Hello_From_Local_Invoke
,这是我们在 template.yml
文件中分配给环境变量 TEST_ENV_VAR
的值。
希望对您有所帮助!
我找到了另一种方法。您可以在自己的本地机器上设置环境变量:
苹果操作系统:
export APP_ID=A
Windows:
SET APP_ID=A
然后 运行 像往常一样使用 mocha 进行测试。
环境变量应在您的环境中定义。如果您想在本地 运行 但更改环境变量 some/all,则可以使用 dotenv
等其他工具。您也可以将这些放在 scripts
部分的 package.json
和 FOO=BAR
中。只要里面没有秘密就可以安全进行。