Reputation: 8704
I want to write integration testing for my API Gateway which is using DynamoDB as backend. I was wondering if there is a method/framework/libraries which provides flexibility to record DynamoDB state before tests and revert it back to original state after the tests?
Ideally, I want something which can keep track changes made in DynamoDB since the beginning of tests and revert all those changes once the test is completed.
Upvotes: 1
Views: 1949
Reputation: 106
as readyornot recommended, i am also using DynamoDBLocal for integration test. I implemented it like with the following concept:-
In the @Before Setup of the Junit class set java library path with the location of the native libs you placed in step 2.
SQLite.setLibraryPath("src/test/resources/location/of/native");
In the setup method as well start the DynamoDB local server with inMemory mode, so you don't need to delete any records after the test finished.
final String[] localArgs = { "-inMemory" };
DynamoDBProxyServer server=ServerRunner.createServerFromCommandLineArgs(localArgs);
server.start();
ddb = AmazonDynamoDBClientBuilder
.standard()
.withEndpointConfiguration(new EndpointConfiguration("http://localhost:8000", "local"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "password")))
.build();
table = createTable(ddb, TABLE_NAME, HASH_KEY_NAME, SORT_KEY_NAME);
Create table like that
private CreateTableResult createTable(AmazonDynamoDB ddb, String tableName, String hashKeyName,
String sortKeyName)
{
List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
attributeDefinitions.add(new AttributeDefinition(hashKeyName, ScalarAttributeType.S));
attributeDefinitions.add(new AttributeDefinition(sortKeyName, ScalarAttributeType.S));
List<KeySchemaElement> ks = new ArrayList<KeySchemaElement>();
ks.add(new KeySchemaElement(hashKeyName, KeyType.HASH));
ks.add(new KeySchemaElement(sortKeyName, KeyType.RANGE));
ProvisionedThroughput provisionedthroughput = new ProvisionedThroughput(1000L, 1000L);
CreateTableRequest request =
new CreateTableRequest()
.withTableName(tableName)
.withAttributeDefinitions(attributeDefinitions)
.withKeySchema(ks)
.withProvisionedThroughput(provisionedthroughput);
return ddb.createTable(request);
}
And here is an example of a test method that tests the table metadata
@Test
public void createTableTest()
{
TableDescription tableDesc = table.getTableDescription();
assertEquals(TABLE_NAME, tableDesc.getTableName());
assertEquals("[{AttributeName: "
+ HASH_KEY_NAME
+ ",KeyType: HASH}, {AttributeName: "
+ SORT_KEY_NAME
+ ",KeyType: RANGE}]",
tableDesc.getKeySchema().toString());
assertEquals("[{AttributeName: "
+ HASH_KEY_NAME
+ ",AttributeType: S}, {AttributeName: "
+ SORT_KEY_NAME
+ ",AttributeType: S}]", tableDesc.getAttributeDefinitions().toString());
assertEquals(Long.valueOf(1000L), tableDesc.getProvisionedThroughput().getReadCapacityUnits());
assertEquals(Long.valueOf(1000L), tableDesc.getProvisionedThroughput().getWriteCapacityUnits());
assertEquals("ACTIVE", tableDesc.getTableStatus());
assertEquals("arn:aws:dynamodb:ddblocal:000000000000:table/" + TABLE_NAME, tableDesc.getTableArn());
ListTablesResult tables = ddb.listTables();
assertEquals(1, tables.getTableNames().size());
}
@After
public void tearDown()
{
ddb.deleteTable(TABLE_NAME);
ddb.shutdown();
}
Upvotes: 0
Reputation: 2863
I use DynamoDB Local in my test environment, instead of running tests against DynamoDB directly. This saves costs and time. I use a test framework (RSpec) where I can delete anything stored in the database after a test is run. http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
If you need to run tests against a real DynamoDB table, look into DynamoDB streams + AWS Lambda. You can write a Lambda function that is triggered on item changes from your table. That function can, for example, store a record of the change in another table. Once your test is done, it can kick off a second Lambda function which goes through the change table and reverts each change in your original table. http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html
Upvotes: 1