【问题标题】:AWS SAM CLI Unit testing Lambda Functions NodeJSAWS SAM CLI 单元测试 Lambda 函数 NodeJS
【发布时间】:2021-01-30 21:04:43
【问题描述】:

我正在使用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 在本地运行我的 lambda 函数。

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

【问题讨论】:

    标签: node.js amazon-web-services aws-lambda mocha.js aws-sam


    【解决方案1】:

    环境变量应在您的环境中定义。如果您想在本地运行但更改部分/全部环境变量,您可以使用其他工具,例如 dotenv。您也可以将这些放在package.jsonscripts 部分和FOO=BAR 中。只要里面没有安全的秘密。

    【讨论】:

      【解决方案2】:

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

      要获得相同的设置,我必须从运行sam init 开始,选择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 文件中读取生产构建,您可以通过运行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 的值。

      希望这会有所帮助!

      【讨论】:

      • 能否请您添加创建.env文件的步骤(位置,格式)以及运行测试时如何使用它?
      • @AndresaMartins 试试this stackoverflow answer
      【解决方案3】:

      我发现了另一种方法。您可以在自己的本地机器中设置环境变量:

      MacOS:

      export APP_ID=A
      

      窗户:

      SET APP_ID=A
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-15
        • 2018-04-26
        • 1970-01-01
        • 2021-03-16
        • 1970-01-01
        • 2017-09-22
        • 1970-01-01
        相关资源
        最近更新 更多