How can I moq nuget package's concrete class with internal constructor with AutoFixture?

Ciao,

I have one solution with my NuGet packages with this structure:

root       
   Directory.Build.props
   MyNuGetPackage1
      NuGetClass.cs
   MyNuGetPackage1.Tests
   MyNuGet.sln

The class NuGetClass.cs has this code:

public class Classe
{
    internal Classe()
    {
​
    }
​
    public int Id { get; set; }
}

In other test project in different solution I reference MyNuGetPackage1 and I need do this:

public class MyTests
{
   Fixture fixture = new Fixture();

   [Test]
   public void MyTest()
   {
      fixture.Build<Classe>().Create(); // This code throw exception, see below for details
   }
}

AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance from AutoFixture.Kernel.SeededRequest because creation unexpectedly failed with exception. Please refer to the inner exception to investigate the root cause of the failure.

Request path: ...

Inner exception messages: AutoFixture.ObjectCreationException: The decorated ISpecimenBuilder could not create a specimen based on the request: Classe. This can happen if the request represents an interface or abstract class; if this is the case, register an ISpecimenBuilder that can create specimens based on the request. If this happens in a strongly typed Build expression, try supplying a factory using one of the IFactoryComposer methods.

​I've tried to update my Directory.Build.props with this configuration:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  ...
  <ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
      <_Parameter1>$(MSBuildProjectName).Tests</_Parameter1>
    </AssemblyAttribute>
  </ItemGroup>
 <ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
       <_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
    </AssemblyAttribute>
 </ItemGroup>
 ...
</Project>

But this configuration works well only with test projects of nuget solution. I should avoid add InternalsVisibleTo manually for each project like this:

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
        <_Parameter1>DestinationProject.Tests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

How can I achieve my goal?

[EDIT]

I've tried thease two approches without success:

CASE 1

[Test]
public void MyTest()
{
   var fixture = new Fixture().Customize(new AutoMoqCustomization());
   var classeMock = fixture.Freeze<Mock<Classe>>();

   fixture.Build<Classe>().Create(); // this code throw exception, see below for details
}

The decorated ISpecimenBuilder could not create a specimen based on the request: Classe. This can happen if the request represents an interface or abstract class; if this is the case, register an ISpecimenBuilder that can create specimens based on the request. If this happens in a strongly typed Build expression, try supplying a factory using one of the IFactoryComposer methods.

CASE 2

[Test]
public void MyTest()
{
   var fixture = new Fixture().Customize(new AutoMoqCustomization());
   var classeMock = fixture.Freeze<Mock<Classe>>();

   fixture.Build<Mock<Classe>>().Create(); // this code throw exception, see below for details
}

Can not instantiate proxy of class: Classe. Could not find a parameterless constructor.

Thanks


Solution 1:

By default AutoFixture does not work with non-public constructors. That includes the internal constructors as well.

Either declare a public (non-copy) constructor or instruct AutoFixture how it should create the class instances.

fixture.Customize<MyClass>(
    c => c.FromFactory(
        () => /* Create your object here. */));