In Memory DynamoDb

Problem

Here at JUST EAT we use DynamoDb in a lot of our components. The DynamoDb API can be awkward and slow to work with at times and this has sometimes lead to a decision between having complicated tests or sacrificing coverage.
Usually our integration tests are run against a QA AWS account that mirrors production. This gives us confidence that our changes are good to push live, but can be slow to iterate on when designing new features. To speed up our cycle time, we wanted a way to decouple our integration tests from AWS without losing confidence in our code.

Solution

Amazon provide a java app that can be used to deploy a local version of DynamoDb. We used this to develop a new feature, and it was the fastest we’ve ever worked with DynamoDb. We decided to wrap it up in a nuget package for use in other projects and when that succeeded just as well we decided to open source it.
The nuget contains a wrapper for this jar file to start and stop it, and provides a DynamoDb client that is configured to use the local instance of dynamo.
This eliminated the need to mock out the complicated DynamoDb api in our tests without sacrificing speed or coverage. It also removed a lot of lines from our tests.
Local Dynamo Test Example

Caveats

There are a couple of potential pitfalls with our approach.
AWS have licensed the DynamoDb jar file in such a way that we couldn’t include it in the nuget. This means that as part of setup, you need to download the file and its dependencies from Amazon and include them in your solution. This has the downside that the version you are testing against has the potential to get out of sync with the version that is running in AWS.
Our QA environments have a mirror of our production security groups, therefore any tests passing in QA give us confidence that our feature will work as intended in production. The local version of DynamoDb provided by Amazon has no concept of security groups, meaning that this aspect of our testing would no longer be covered. To ensure security groups continued to be tested adequately, we implemented a dependency check endpoint in our API that executes a read and write against dynamo and returns an http response giving success or failure information. This check is run post-deploy and has to pass before a deployment is considered successful.
Dependency Check Example
 
The project is available on nuget: nuget.org/packages/LocalDynamoDb and on github at: github.com/justeat/LocalDynamoDb
Alan NicholsSteve Brazier

  1. I have a question, why did you have to write a InMemory DynamoDb implementation? You could use the Repository Pattern (http://martinfowler.com/eaaCatalog/repository.html) so you could abstract the implementation of the persistent method.
    With Repository you can test in integration (with real DynamoDb) only the repository itself and you can use the InMemory version (or a dummy version or a mock) of the repository for every integration tests and unit test.
    With this solution, also, you have the possibility to put in one place every logic about DynamoDb (DynamoDbRepository) and abstract your codebase, mainly your business domain, about the persistent logic.
    Did you think about it? There’s problems to use repository pattern in this case?
    Thanks you so much
    Ettore

Comments are closed.