How to write unit tests when using the AWS JavaScript SDK v3?
Writing unit tests for code that interacts with the AWS JavaScript SDK v3 comes with two major benefits. Obviously, writing unit tests ensures you catch bugs early and therefore increase the quality of your code. Also, writing unit tests enables you to run your code locally without the need to reach out to the AWS service APIs. But how do you write unit tests for code interacting with the AWS JavaScript SDK v3?
In the following, I will share my learnings from writing unit tests by using aws-sdk-client-mock by Maciej Radzikowski.
aws-sdk-client-mock is simple to use!
Let’s start with a simple example.
The following code snippet shows the index.js
file containing a handler()
function, which could be deployed as a Lambda function. The handler()
function lists all buckets belonging to an AWS account.
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3'; |
So, how do I write a unit test? I prefer using the test framework mocha to write JavaScript tests. The following snippet shows the test/test.index.js
file containing the skeleton to implement a test.
import { deepStrictEqual } from 'node:assert'; |
When executing the test, the handler()
function will send a request to the S3 API. But doing so is not feasible for unit testing, as it is very challenging to ensure the response matches the assumptions in the unit test.
Instead of sending requests to the AWS APIs use a common testing technique called mocking. A mock simulates a dependency. So let’s mock the AWS Java Script SDK v3 by extending the test/test.index.js
file.
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3'; |
Want to run the example yourself? Here is the package.json
that you need to setup the example.
{ |
Finally, run the test.
npm i |
The testing framework outputs the following results.
> aws-mock-demo@1.0.0 test |
Next, let me share a some lessons learned.
Creating a mock with aws-sdk-client-mock
It took me a little bit to understand that there are two ways to create a mock.
The following code creates a mock for a given client instance.
const s3Client = new S3Client({}); |
However, in many scenarios, you don’t have access to the AWS SDK client instances. In those scenarios, here is how you globally mock a client.
const s3Mock = mockClient(S3Client); |
Testing pagination
The AWS JavaScript SDK v3 comes with built-in paginators. The following snippet shows how to page through all items stored in a DynamoDB table.
import { DynamoDBClient, paginateScan } from '@aws-sdk/client-dynamodb'; |
To write a unit test override the underlying command, ScanCommand
in this example.
import { DynamoDBClient, ScanCommand } from '@aws-sdk/client-dynamodb'; |
Mocks vs. real-world
The tricky part when writing mocks for the AWS SDK is to ensure comatiblity with the real-world. That’s why I do not rely on unit testing. On top of that, integration testing against the AWS APIs is necessary.
Summary
aws-sdk-client-mock is a handy tool when it comes to writing unit tests for code that interacts with the AWS JavaScript SDK v3. It has never been easier to write unit tests!
Further reading
- Article Migrating to AWS JavaScript SDK v3: Lessons Learned
- Article Tidying up after failed Terraform tests
- Article How to monetize an API on AWS?
- Tag sdk