Decided to update this answer as a few people have bookmarked this question.
To get the same setup I have to start with run sam init
, select the AWS Quick Start Templates
, the run time is nodejs12.x
and the application template to use is Quick Start: From Scratch
.
After this step you should have a directory structure that looks like this below in your sam application.
-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
Run an npm install
to install the dependecies which creates your node_modules
directory.
After this has finished run the following command to install the dotenv
module.
npm install dotenv
Create a file named .env
in the root directory. Your root directory should now look like this.
-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
Now in your .env
file create an environment variable like my sample one below.
TEST_ENV_VAR=HELLO_FROM_TEST
In your template.yml
file also define an environment variable of the same name but give it a different value so we can see when the two different locations are being read in the next step.
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
In the handler file located at src/handlers/hello-from-lambda.js
change the code to the following which is reading in the environment varibale TEST_ENV_VAR
and returning it.
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;
}
In your test handler located at __tests__/unit/handlers/hello-from-lambda.test.js
paste the following code. It reads the environment variables from the .env
you created earlier using the dotenv
module. The test will now pass if the value returned from the helloFromLambdaHandler
is equal to the value HELLO_FROM_TEST
which is the value we defined for the environment variable TEST_ENV_VAR
in the .env
file.
// 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);
});
});
Now run the test by running the command npm run test
in the root directory, it passes showing that we are reading from the .env
for test cases.
$ 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.
To prove we are reading from the template.yml
file for production builds you can invoke a local test by running sam build
to build the project and then sam local invoke
all from the root directory.
$ 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"
You can see we now get the value Hello_From_Local_Invoke
which is the value we assigned to the environment variable TEST_ENV_VAR
in the template.yml
file.
Hope this helps!