Node.js AWS SAM CLI单元测试Lambda功能节点JS

Node.js AWS SAM CLI单元测试Lambda功能节点JS,node.js,amazon-web-services,aws-lambda,mocha.js,aws-sam,Node.js,Amazon Web Services,Aws Lambda,Mocha.js,Aws Sam,我正在使用来测试和部署AWS Lambda函数。我试图在NodeJS中使用Mocha和Chai运行单元测试。测试位于test目录中,我可以使用命令mocha--recursive运行测试 问题是我在测试中使用了环境变量。我的环境变量在SAM CLI的template.yaml文件中定义。它看起来像这样: RefreshFunction: Type: AWS::Serverless::Function Properties: Handler: src/handler

我正在使用来测试和部署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在本地运行lambda函数


是否有人知道
sam local invoke
命令可用于运行lambda函数的本地测试用例?或者如何从使用mocha和chai的测试用例中访问
template.yaml
文件中的我的环境变量?

决定更新此答案,因为一些人已将此问题添加到书签中

要获得相同的设置,我必须先运行
sam init
,选择
AWS快速启动模板
,运行时间是
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安装
以安装创建
node\u模块
目录的依赖项。 完成后,运行以下命令安装
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
的处理程序文件中,将代码更改为以下代码,该代码正在环境varible
TEST\u ENV\u 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;
}
在位于lambda.test.js的测试处理程序中,粘贴以下代码。它从先前使用
dotenv
模块创建的
.env
中读取环境变量。如果从helloFromLambdaHandler返回的值等于从_test返回的值HELLO_,则测试现在将通过,该值是我们在
.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
文件,您可以通过运行
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"
您可以看到,我们现在从_Local_Invoke获取值
Hello\u,这是我们在
template.yml
文件中分配给环境变量
TEST\u ENV\u 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);
    });
});

希望这有帮助

我找到了另一种方法。您可以在自己的本地计算机中设置环境变量:

马科斯:

export APP_ID=A
窗口:

SET APP_ID=A

然后像往常一样使用mocha运行测试。

环境变量将在您的环境中定义。如果希望在本地运行,但更改部分/所有环境变量,则可以使用其他工具,如
dotenv
。您还可以使用
FOO=BAR
将它们放在
scripts
部分的
package.json
中。只要里面没有安全的秘密就可以了。

您可以添加创建.env文件的步骤(位置、格式)以及运行测试时如何使用它吗?@Andresmartins try