Unit Testing AWS Lambda Functions in Node.js

I’m a big fan of writing unit tests and get very upset if those working on projects don’t write them. I also like to document my tests with how they’re written. I’ve been using Node.js for the past couple of years and use the Mocha and Chai (expect) frameworks extensively within my projects.

When I started to write Lambda functions using Node.js, I didn’t find frameworks that I enjoyed using. I ended up writing my own helper utilities to make testing Lambdas easier and less painful.

The Old Way

Let’s test with my basic go to frameworks, Mocha and Chai, and use a very simple Lambda function just to facilitate the examples in this article.

The following represents the Lambda function that we want to test:

To cover the code fully, we would want to test the name being equal to ‘Richard’ and ‘rhyatt’, the name being something else and just for fun the name being not set (undefined).

So our test code, using some loops for valid/invalid cases would look like:

Our project structure should look as follows:
/example
index.js
package.json
/node modules
/test
index.test.js

Running the above test against our handler, we should get the following output:

vandium-rhyatt:myLambda rhyatt$ mocha test
myLambda
✓ successful invocation: name=Richard
✓ successful invocation: name=rhyatt
✓ fail: when name is invalid: name=Fred
✓ fail: when name is invalid: name=undefined
4 passing (10ms)

Great our tests work and if were to run a code coverage tool, like istanbul, we would have full coverage. But if the code was a little more complicated, we might be in for some real trouble.

New Way — Using Lambda Tester

After writing several versions of test utilities, discussing best practices with other developers, and them repeatedly asking to use my test code, it dawned on me that others were experiencing a similar pain (or just not writing tests!). I open sourced my tool under the name “lambda-tester” and it’s available via NPM.

To use it in your project:

npm install lambda-tester --save-dev

Let’s start making Lambda functions easier and less painful to test. The following code is the same set of tests, but this time we’re using lambda-tester:

And when we run it:

vandium-rhyatt:myLambda rhyatt$ mocha test
myLambda
✓ successful invocation: name=Richard
✓ successful invocation: name=rhyatt
✓ fail: when name is invalid: name=Fred
✓ fail: when name is invalid: name=undefined
4 passing (9ms)

Our new set of tests are 44 lines long compared to the 76 in the old method. If our Lambda expression actually did something and was more complicated, we might see a larger difference in the amount of code.

When using lambda-tester it is *important* that you return the LambdaTester instance to the test framework because it uses JavaScript Promises to handle asynchronous operations. Failing to do this step will cause the lambda-tester to not work as expected and the test to fail.

Wrapping it Up

Not only does lambda-tester reduce the amount of work that you need to do in your tests, but it makes your tests easier to read and maintain. The built-in asynchronous design using Promises internally reduces the need for complicated callback logic. If your Lambda function throws and error or follows the wrong path, lambda-tester will identify the issue and fail the test.


If you enjoyed this article and are writing handlers for AWS Lambda, please check out our sister project, Vandium, that simplifies writing Lambda handlers: