Integration testing tool for DynamoDB
Tags: serverless, testing, typescript, aws
Published: 2022-01-11 13:49:11

Integration testing in serverless architectures can be challenging. Testing specific outcomes within managed services is cumbersome. [sls-test-tools](https://github.com/Theodo-UK/sls-test-tools) provides a range of utilities, setup, teardown and assertions to make it easier to write effective and high quality integration tests for Serverless Architectures on AWS.

I’m happy to announce that sls-test-tools now ships with new DynamoDB assertions!

Let's jump in a quick example 🏃‍♂️ !

## 1️⃣ Function to test

Let's consider a simple Lambda function that uploads client transaction data to DynamoDB.

![Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcbz8weo05o0qcsuxtid.png)

``` ts
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb";

type TransactionEvent = { clientName: string; transactionData: string };

const ddbDocClient = DynamoDBDocumentClient.from(new DynamoDBClient({}));

export const handler = async (event: TransactionEvent): Promise<string> => {
  const { clientName, transactionData } = event;

  await ddbDocClient.send(
    new PutCommand({
      TableName: "Sells",
      Item: {
        PK: clientName,
        SK: new Date().toISOString(),
        transactionData,
      },
    })
  );

  return "Transaction saved !";
};
```
As you can see, the function just makes a single "put" call to DynamoDB using the AWS SDK. In our integration test we want to make sure that the data has indeed been written to Dynamo.

## 2️⃣ Writing the test!

We will be using sls-test-tools new assertion `toExistInDynamoTable`.
The integration testing can be done in 3 phases:

1. Triggering the initial event 🔥. In our scenario we call our lambda handler but we could also imagine sending an event in an Event Bus, uploading a file to S3...

2. Asserting the expected behavior ✅. 

3. Cleaning what has been created 🧹. This step is very important in order to keep tests idempotent.

Following these three steps, the integration test implementation would be:
``` ts
import { DocumentClient } from "aws-sdk/clients/dynamodb";
import MockDate from "mockdate";
import { AWSClient } from "sls-test-tools";

import { handler } from "./uploadTransactionDataToDynamo";

describe("Sells data upload integration testing", () => {
  const documentClient: DocumentClient = new AWSClient.DocumentClient();

  const mockDate = "2022-01-01T00:00:00.000Z";
  MockDate.set(mockDate);

  const event = { clientName: "John", transactionData: "someData" };

  afterAll(async () => {
    // 🧹 clean what you've created
    await documentClient.delete({
      TableName: "Sells",
      Key: { PK: "John", SK: mockDate },
    });
  });

  it("should upload transaction data to Dynamo", async () => {
    // 🔥 trigger the initial event
    await handler(event);

    // ✅ assert the functional behavior you are testing
    await expect({
      PK: "John",
      SK: mockDate,
    }).toExistInDynamoTable("Sells");
  });

```
All sls-test-tools assertions can of course be inverted using `expect(..).not`.

---

You can use those assertions on all type of DynamoDB table, on a composite primary index table containing a partition key `PK` and a sort key `SK` like in the previous example, as well as in simpler table where primary index is only a partition key.

```ts
it("should upload transaction data to Dynamo", async () => {
  await handler(event);

  await expect({ PK: "John" }).toExistInDynamoTable("Sells");

  await documentClient.delete({
    TableName: "Sells",
    Key: { PK: "John", SK: mockDate },
  });
});
```
 

## 3️⃣ What's next !

Our team is working on typing sls-test-tools and on adding more custom jest assertions. We are also writing a more exhaustive article on Serverless integration testing, please feel free to subscribe so you can be notified when it will come out!


⭐️⭐️⭐️ Happy 2️⃣0️⃣2️⃣2️⃣ ⭐️⭐️⭐️

For more background about sls-test-tools, you can check out these two articles: [Integration Testing Strategy for EventBridge ](https://medium.com/serverless-transformation/bridge-integrity-integration-testing-strategy-for-eventbridge-based-serverless-architectures-b73529397251) and [Bringing Simplicity to Serverless Integration Testing](https://medium.com/serverless-transformation/announcing-the-alpha-release-of-sls-t[…]bring-simplicity-to-serverless-integration-testing-a5a5ccabde43).