
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
dynamodb-testing-tool
Advanced tools
DynamoDB is fantastic tool, but so far it misses a nice abstraction that would make you more confident that the code you write is correct. All those string based queries and parameters probably make you uncomfortable, especially if you are coming from the easy-land of mongodb. Writing nodejs scripts to set tables up and run methods on them quickly gets tiring, without the fantastic workflow that tools like Jest and WallabyJS provide you. This tool will allow you to iterate quickly while working with DynamoDB.
We will start the DynamoDB in the background for you (assuming you have Java SDK, if not, you will have to install it). That should also work on CIs! Locally, we suggest running dynamodb in the background on port 4567 (run your tests with DYNAMO_TEST_PORT env variables if you want to use a different one) to make things faster.
We dynamically create and delete tables for your tests behind the scenes, to make sure there are no "collisions" or "race conditions".
There is not much API to the library. You call createTable with an input defined by DynamoDB.CreateTableInput. That returns an object that has inside two things - the generated name, documentClient which you can use to perform operations.
import { DynamoDB } from "aws-sdk";
import {
CreatedTable,
createTable,
generateRandomName,
} from "dynamodb-testing-tool";
let tableObject: CreatedTable;
describe("Multiple tests do not collide with each other", () => {
beforeEach(async () => {
const dynamoSchema: DynamoDB.CreateTableInput = {
TableName: generateRandomName(),
AttributeDefinitions: [{ AttributeType: "N", AttributeName: "id" }],
KeySchema: [{ AttributeName: "id", KeyType: "HASH" }],
BillingMode: "PAY_PER_REQUEST",
};
tableObject = await createTable(dynamoSchema);
});
test("Adding an item and getting all should return one item", async () => {
await tableObject.documentClient
.put({
TableName: tableObject.tableName,
Item: { id: 1, somethingElse: true },
})
.promise();
const results = await tableObject.documentClient
.scan({ TableName: tableObject.tableName })
.promise();
expect(results.Items).toHaveLength(1);
// @ts-ignore
expect(results.Items[0]).toMatchObject({ somethingElse: true });
});
test("Adding another item and getting all should still return one item", async () => {
await tableObject.documentClient
.put({
TableName: tableObject.tableName,
Item: { id: 2, somethingElse: false },
})
.promise();
const results = await tableObject.documentClient
.scan({ TableName: tableObject.tableName })
.promise();
expect(results.Items).toHaveLength(1);
// @ts-ignore
expect(results.Items[0]).toMatchObject({ somethingElse: false });
});
});
We remove tables automatically, even though the names do not collide with each other, dynamodb starts to slow down with hundreds of tables, especially if they use the same indexes (and they will if you recreate tables with the same shapes over and over). this method makes the tooling remove the table after all tests in a given file or block finished. The use-case is similar to keepTable, but the table will get dynamically recreated from scratch on every test run. This might be useful in initial phase when you want to frequently change the table definition and it's items. If you work with small amount of items and you are only concerned about testing reads from a pre-populated table, it's probably best to use this option. It's plenty fast and convenient.
If you want to avoid removing tables altogether, pass {keepTable: true} as an option to createTable function. That option does two things:
This is especially useful if you want to test multiple different ways of querying your dataset, but do not want to wait hundreds of milliseconds or even seconds for the db to get populated over and over. Imagine inserting a milion records to dynamodb and being able to test different read patterns with wallabyjs. Dream come true!
Example:
import { DynamoDB } from "aws-sdk";
import { createTable } from "dynamodb-testing-tool";
const dynamoSchema: DynamoDB.CreateTableInput = {
TableName: "fixedName",
AttributeDefinitions: [{ AttributeType: "N", AttributeName: "id" }],
KeySchema: [{ AttributeName: "id", KeyType: "HASH" }],
BillingMode: "PAY_PER_REQUEST",
};
test("keepTable option disallows changing the table if it finds the table with items already", async () => {
const { documentClient, tableName } = await createTable(dynamoSchema, {
keepTable: true,
});
await documentClient
.put({
TableName: tableName,
Item: { id: 1, somethingElse: true },
})
.promise();
let results = await documentClient.scan({ TableName: tableName }).promise();
expect(results.Items).toHaveLength(1);
await createTable(dynamoSchema, { keepTable: true });
await documentClient
.put({
TableName: tableName,
Item: { id: 1, somethingElse: true },
})
.promise();
results = await documentClient.scan({ TableName: tableName }).promise();
expect(results.Items).toHaveLength(1);
});
If your CI fails and you see this scary error: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error: Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout. or/and this one: TypeError: Cannot read property 'documentClient' of undefined
That means your CI was too slow to startup the dynamodb. You might need to increase the jest timeout, take a look here: https://jestjs.io/docs/en/jest-object#jestsettimeouttimeout
If you see this error: ResourceInUseException: Cannot create preexisting table that might mean that you are generating the randomName not often enough. For example:
const dynamoSchema: DynamoDB.CreateTableInput = {
TableName: generateRandomName(),
AttributeDefinitions: [{ AttributeType: "N", AttributeName: "id" }],
KeySchema: [{ AttributeName: "id", KeyType: "HASH" }],
BillingMode: "PAY_PER_REQUEST",
};
beforeEach(async () => {
tableObject = await createTable(dynamoSchema);
});
Will not work, because the dynamoSchema object will get defined once, and all calls to createTables will reuse the same name. change it to this:
beforeEach(async () => {
const dynamoSchema: DynamoDB.CreateTableInput = {
TableName: generateRandomName(),
AttributeDefinitions: [{ AttributeType: "N", AttributeName: "id" }],
KeySchema: [{ AttributeName: "id", KeyType: "HASH" }],
BillingMode: "PAY_PER_REQUEST",
};
tableObject = await createTable(dynamoSchema);
});
FAQs
### Why?
We found that dynamodb-testing-tool demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.