Skip to content

Cannot mock DynamoDBContext.CreateBatchGet due to lack of interfaces #1396

Closed
@krzysztof-at-mp

Description

@krzysztof-at-mp

When I try write unit test for code which uses DynamoDBContext.CreateBatchGet I'm stuck on providing fake results. The BatchGet does not have a public available constructor nor does CreateBatchGet use an interface for return type.

Expected Behavior

The easiest way would be to add IBatchGet interface and add it as a return type for CreateBatchGet. This would allow easily provide mock when using IDynamoDbContext and return fake data for my tests.

Current Behavior

BatchGet cannot be instantiated so I'm forced to use concrete type like DynamoDbContext.

IAmazonDynamoDB client = Substitute.For<IAmazonDynamoDB>(); IDynamoDBContext context = new DynamoDBContext(client, new DynamoDBOperationConfig { OverrideTableName = "Abc" }); BatchGet<T> batch = context.CreateBatchGet<T>(); await batch.ExecuteAsync();

Having this done I strange exceptions from SDK internals like

System.NullReferenceException : Object reference not set to an instance of an object. at Amazon.DynamoDBv2.DocumentModel.Table.DescribeTable(String tableName)

and still I see no easy way to return results :(

I could do some tweaks in my code by adding some unwanted entity attributes and be able go over this issue but then I'm at executing the batch and still there is no easy way to provide the results. I could do:

IDynamoDBContext context = Substitute.For<IDynamoDBContext>(); BatchGet<T> batch = context.CreateBatchGet<T>(); await batch.ExecuteAsync();

but in this case I cannot find an easy way to provide fake data through the mocked IDynamoDBContext nor mocked IAmazonDynamoDB.

I also cannot return fake data by using another approach

IDynamoDBContext context = Substitute.ForPartsOf<DynamoDBContext>(); BatchGet<T> batch = context.CreateBatchGet<T>(...) context.ExecuteBatchGetAsync(new BatchGet[] { batch })

because in this case the ExecuteBatchGetAsync public method is not marked as virtual so it's difficult to ovverride that call using eg. NSubstitute.

Possible Solution

Add IBatchGet interface for CreateBatchGet in IDynamoDBContext.
(or) Make ExecuteBatchGetAsync virtual in DynamoDBContext

I can provide a pull request for this change if you feel you need one :)

Steps to Reproduce (for bugs)

Write unit test which returns fake data from the batch API.

Your Environment

  • AWSSDK.DynamoDBv2 (3.3.101.59)

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking-changeThis issue requires a breaking change to remediate.bugThis issue is a bug.dynamodbneeds-major-versionCan only be considered for the next major releasep2This is a standard priority issuequeuedv4

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions