I’ve recently been working on a new project that uses AWS DynamoDB as the database. I wanted to start writing meaningful end-to-end tests to make sure everything was working as expected, but I ran into a familiar challenge: end-to-end testing usually either means mocking the database (which is really annoying to setup) or running a test instance of the database which is fine locally, but can be a big pain to set up and maintain in CI.
What I needed was something fast, lightweight, and easy to integrate into our existing Jest test suite. Ideally, it wouldn’t require Docker or an external process to be running just to execute a few database tests. That’s when I came across Jest’s DynamoDB shelf, a small utility that wraps DynamoDB Local and makes it incredibly simple to spin up a temporary, in-memory instance right from within your tests.
The Problem with Testing DynamoDB Locally
Mocking out your database is definitely an option for testing, but it comes with some pretty significant drawbacks. What I don’t like about mocking is the fact that they don’t reflect the real behavior of what you’re testing, just how you think it behaves. It also mocks how something currently works, but as dependencies get updated that is likely to change which will require more maintenance to keep up-to-date. Mocking is also notorious for causing false positives.
On the flipside, the official Jest documentation outlines a solid approach using Docker to spin up a local DynamoDB instance before tests run. It works well, but brings along some extra setup and complexity, especially when trying to run those same tests in a CI environment where managing Docker or shared resources can be a huge pain.
That’s where Jests’s DyanamoDB shelf comes in.
A Better Approach: In-Memory DynamoDB with Shelf
Shelf provides a clean abstraction around DynamoDB Local. It lets you spin up an actual DynamoDB instance entirely in memory. That means no Docker, no separate processes, and nothing to manage outside your test runner. That means tests can run quickly, reliably, and in isolation. Perfect for continuous integration pipelines.
Setup
Honestly, just follow Jest’s guide to get this up and running in your Node.js app. It’s super simple and straightforward.
Why This Has Worked So Well
Here’s why this approach has been working great for me:
- CI-ready by default – No need to install or manage DynamoDB as a service. Tests run cleanly anywhere Node can run.
- Real database behavior – You’re testing against an actual instance of DynamoDB (albeit in memory), so query logic and validation are exercised for real.
- Fast execution – Because the database is in-memory and starts/stops with your test suite, tests are quick and disposable.
- Minimal config – Just install Shelf and drop in a few lifecycle hooks. That’s it.
The only caveat is that you’ll need to define your tables before running your tests, just like you would in a production setup. I’ve handled this by creating a createTables utility function and calling it from beforeAll. It keeps things clean and avoids duplication across test files.
Final Thoughts
If you’re working with DynamoDB and looking for a way to write robust tests that can run both locally and in CI without additional overhead, Shelf is a great tool to reach for. It removes a lot of friction from integration testing and has helped me write better, more confident tests—without sacrificing speed or simplicity.
It’s definitely made testing a lot more enjoyable on this new project, and I think it’s a tool worth adding to your stack.