Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to mock Table object returned from IDynamoDBContext.GetTargetTable #1310

Closed
IIFE opened this issue Jun 10, 2019 · 11 comments
Closed

Unable to mock Table object returned from IDynamoDBContext.GetTargetTable #1310

IIFE opened this issue Jun 10, 2019 · 11 comments
Labels
dynamodb feature-request A feature should be added or improved. needs-major-version Can only be considered for the next major release p1 This is a high priority issue queued v4

Comments

@IIFE
Copy link

IIFE commented Jun 10, 2019

Unable to mock Table object returned from IDynamoDBContext.GetTargetTable

I am injecting IDynamoDBContext in a constructor, and then calling GetTargetTable to get the Table object representing the table for an entity. I then use that Table object to carry out some operations on DynamoDB, or to extract metadata about the table (i.e table name, hash key name, etc).

The problem is I cannot find a way to mock the return value of GetTargetTable as the Table class doesn't appear to be mockable.

Expected Behavior

I would expect GetTargetTable to return an interface that defines the operations which can be carried out on an entity's table, rather than the concrete Table implementation.

Current Behavior

GetTargetTable returns concrete class rather than an abstraction (i.e interface)

Possible Solution

Create an interface abstract over the Table class and have GetTargetTabke return the interface.

Steps to Reproduce (for bugs)

Following class shows an example of the issue:

public class EntityBase
{
	public string Id { get; set; }
}
	
public class DynamoDBRepository<TEntity>
	where TEntity : EntityBase
{
	private IDynamoDBContext DbContext { get; }

	private Table Table { get; }

	private ITableMetadata TableMetadata { get; }

	public DynamoDBRepository(IDynamoDBContext dbContext)
	{			
		DbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
			
		Table = DbContext.GetTargetTable<TEntity>()
			?? throw new InvalidOperationException($"Unable to retrieve table information for {typeof(TEntity).FullName} from {nameof(IDynamoDBContext)}");

		TableMetadata = new TableMetadata(Table.TableName, Table.HashKeys?.FirstOrDefault(), Table.RangeKeys?.FirstOrDefault());
	}

	public async Task UpdateAsync(TEntity entity)
	{			
		ExpectedState state = new ExpectedState();
		state.AddExpected(TableMetadata.IdName, ScanOperator.Equal, entity.Id);

                // Cannot mock this.
		await Table.UpdateItemAsync(DbContext.ToDocument(entity), new UpdateItemOperationConfig{ ExpectedState = state});
	}
}

Context

Unable to unit tests services that consume IDynamoDBContext and rely on the instance returned by GetTargetTable to carry out certain operations.

Your Environment

  • AWSSDK.Core version used: 2.1
@klaytaybai
Copy link
Contributor

Thanks for the feedback.

@klaytaybai klaytaybai added the feature-request A feature should be added or improved. label Jun 10, 2019
@mbp
Copy link

mbp commented Sep 20, 2019

Basically the same as #632 which is added to feature request backlog 2.5 years ago. Wouldn't count on it to happen...

@klaytaybai
Copy link
Contributor

We do have some other issues around this topic too, but it is unlikely to happen until a next major version.

@kwbauer
Copy link

kwbauer commented Jan 14, 2020

Or add a public parameterless constructor. That way mocking frameworks can construct the object and we can mock the properties and methods we need to.

The main problem is that most of these objects have no public constructors at all. Sure, they aren't needed for the library but it makes our code which uses your library not testable.

Adding the public constructors is a good compromise that is fairly easy to do for a minor revision as it is not a breaking change.

@klaytaybai klaytaybai added breaking-change This issue requires a breaking change to remediate. and removed needs-major-version labels Feb 27, 2020
@nicollaas94
Copy link

Is there a feature-request list where we can vote on this one?
creating wrappers for testing our services is becoming annoying and far from ideal

@AdamLewisGMSL
Copy link

AdamLewisGMSL commented Mar 15, 2021

Adding my voice to this. Currently have a whole tranche of code I can't test because I can't mock the types in the DynamoDb package. This is one of them.

@Darren-Kelly
Copy link

I also just ran into the same issue when trying to add unit tests. I cannot mock the Table class.

@brenocg1
Copy link

Hello,

Any update regarding this?

@dcorrea777
Copy link

dcorrea777 commented Jul 20, 2022

I also have the same problem, I can't seem to mock some classes to do my unit tests.

The problem is that the maintainers say: "we accept PRS" but there are several open PRs that are even more than a year old.

@ik130 ik130 added p1 This is a high priority issue needs-major-version Can only be considered for the next major release and removed breaking-change This issue requires a breaking change to remediate. labels Dec 1, 2022
@96malhar
Copy link
Contributor

Hello, we have been working on the V4 of the AWS SDK for .NET. We have added the ability to mock various DynamoDB operations by adding interfaces in both the Data Model mode and Document Model mode in DynamoDB.

Refer to this PR - #3450

Specifically for the IDynamoDBContext.GetTargetTable methods, it now returns an ITable interface which is implemented the by the Table class. The interface can be mocked to simulate table operations in unit tests.

This feature is available in the AWSSDK.DynamoDBv2 Version 4.0.0-preview.2

Copy link

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dynamodb feature-request A feature should be added or improved. needs-major-version Can only be considered for the next major release p1 This is a high priority issue queued v4
Projects
None yet
Development

No branches or pull requests