Creation fake of Amazon.DynamoDBv2.DocumentModel.Search with FakeItEasy

27 Views Asked by At

I may doing something wrong but can't find the answer.

It seems that line

var searchFake = A.Fake<Search>(); 

should simply work. But it always gives me the error

Constructor with signature () failed: No usable default constructor was found on the type Amazon.DynamoDBv2.DocumentModel.Search.

While Search type actually has internal parameterless constructor and I simply could create instance of this type with the next code:

  var constructor = typeof(Search).GetConstructors(BindingFlags.NonPublic | 
       BindingFlags.Instance).Single(c => c.GetParameters().Length == 0);
       
  var instance = Activator.CreateInstance(typeof(Search), nonPublic: true)   
       as Search;

Why FakeItEasy unable to do so or what I'm doing wrong here?

1

There are 1 best solutions below

1
Blair Conrad On

Why FakeItEasy unable to do so or what I'm doing wrong here?

FakeItEasy's unable to do so because it uses Castle DynamicProxy to create the Fakes, and this is how DynamicProxy works.

Could these libraries work around the issue, possibly via a reflection trick not unlike the one you mentioned above? Probably, but it's not something they do today.

The FakeItEasy documentation, specifically the section what types can be faked?, indicates that

special steps will need to be taken to fake internal interfaces and classes

In your case, it seems the class is public, but the constructor is not, but the suggested steps apply anyhow: making the internals of the assembly containing the class to be faked visible to DynamicProxyGenAssembly2.

I don't know this for sure, but suspect that you don't have control over the assembly that contains Amazon.DynamoDBv2.DocumentModel.Search. So you might have to be a little more creative. Perhaps introduce an interface that could be implemented by a proxy class of your own (that also is derived from Amazon.DynamoDBv2.DocumentModel.Search). Then you could fake the interface. Your production code would have to change to instantiate this new class, though.