/ aws

Nodejs makes testing AWS Lambda easy!

Testing in Isolation has benefits

Testing AWS lambda functions at the surface is done through AWS's interface. This gets a little arduous after a while.

You get one sample event you can create. Great for quickly trying something in deployment, but not very useful for iterating quickly over a feature.

Their own testing template is to create another lambda function to test the first one. So you end up with a set of curl commands effectively calling a lambda with a json payload to call your other lambda. Turtles anyone?

Sometimes you just want to work out some logic issue while you're commuting and don't have a consistent internet connection (my situation). Or you don't want to jump through the AWS hoops to test things the way they have defined in their sample template.

I did a little poking around and figured out how to get this thing working locally so I can get continuous integration runs of tests.

Project Setup

As of this post, lambda functions can be one of 3 languages. Python, Nodejs, or Java.
For this I am using Nodejs and for good reason. It's probably the most flexible when it comes to deployment and testing, and the ability to mock out objects is honestly second to none.

This test should work with the examples over at the AWS developer pages

We're going to install 3 packages to get this going. If you already have your own testing framework defined, that's ok, you can just follow the information about the Mock Context from the link below.

npm install aws-lambda-mock-context mocha chai --save-dev

Test File

Here is an example that should work with any lambda statement, this example is a new session event

var expect = require('chai').expect,
lambdaToTest = require('../index')

const context = require('aws-lambda-mock-context');
const ctx = context();

describe('When Starting a Session', function() {
    var speechResponse = null
    var speechError = null

    // Fires once for the group of tests, done is mocha's callback to 
    // let it know that an   async operation has completed before running the rest 
    // of the tests, 2000ms is the default timeout though
    before(function(done){
        //This fires the event as if a Lambda call was being sent in
        lambdaToTest.handler({
        "session": {
        "new": true,
        "sessionId": "session1234",
        "attributes": {},
        "user": {
        "userId": null
        },
        "application": {
        "applicationId": "amzn1.echo-sdk-ams.app.1234567"
        }
        },
        "version": "1.0",
        "request": {
        "type": "LaunchRequest",
        "requestId": "request5678"
        }
    },ctx)

    //Captures the response and/or errors
    ctx.Promise
        .then(resp => { speechResponse = resp; done(); })
        .catch(err => { speechError = err; done();})
    })
    

    describe('The response is structurally correct for Alexa Speech Services', function() {
        it('should not have errored',function() {
            expect(speechError).to.be.null
        })

        it('should have a version', function() {
            expect(speechResponse.version).not.to.be.null
        })

        it('should have a speechlet response', function() {
            expect(speechResponse.response).not.to.be.null
        })

        it('should have session attributes', function() {
            expect(speechResponse.response.sessionAttributes).not.to.be.null
        })

        it('should leave the Alexa session open', function() {
            expect(speechResponse.response.shouldEndSession).not.to.be.null
            expect(speechResponse.response.shouldEndSession).to.be.false
        })
    })
})

Output

In Conclusion

Testing AWS Lambda functions when using Nodejs as a packaging strategy is easy. Nodejs lends itself to easy testing, and the ability to create mock context objects that emulate behaviors.

With all of this, you can create a rich Lambda Function with tests to back it up, and less infrastructure in AWS to test it.

Nodejs makes testing AWS Lambda easy!
Share this