Writing serverless functions brings developers closer and closer to the stack that runs their code. While this gives them a tremendous amount of freedom, it also adds additional responsibility. Serverless applications require developers to think more about security and optimizations, as well as perform other tasks that were traditionally assigned to operations teams. And of course, code quality and proper testing continue to be at the top of the list for production-level applications. In this post, we’ll look at how to add test coverage to our Node.js applications and how we can apply it to our Serverless framework projects. ⚡️
I know the title is a quite a mouthful, but if you are trying to run tests on your Lambda functions that interact with AWS Services using the
aws-sdk node module, then you’ve probably run into an issue stubbing or mocking the requests. In this post we’ll learn how to stub different AWS Services with Sinon.JS so that you can properly test your scripts.
UPDATE: AWS Lambda now supports Node v8.10, so we can use
async/await instead of promises. The examples below still work with either v6.10 or v8.10, however, I recommend switching to
async/await as they are more compact than promises. Read my post How To: Stub “.promise()” in AWS-SDK Node.js to learn how to deal with the
.promise() method on aws-sdk services.
Let’s say you have a Lambda function that interacts with AWS’s SQS (Simple Queue Service). v6.10 of Node doesn’t support
async/await, so you will most likely use promises if you don’t want to transpile your code or deal with callback hell. This means you need to Promisify an instance of the AWS SQS service. This is easy enough with:
const AWS = require('aws-sdk') // AWS SDK
const Promise = require('bluebird') // Promise library
const SQS = Promise.promisifyAll(new AWS.SQS())
There are a lot of methodologies available for development. I’ve done everything from Agile to Waterfall, either iterating as we go, or planning a really large project all the way through upfront. I’ve found pros and cons to all the different methodologies, but in the end, I prefer to take an iterative approach. The problem with iterating quickly, or as Mark Zuckerberg would say, “Move fast and break something”, is that you do, in fact, break things. In smaller codebases this might not be that big of a deal, but when dealing with larger scale production systems, breaking something is simply not tolerable. A good solution I’ve found is to implement a “Test First” development methodology where you building unit testing first, and then write the code to pass the tests.