I'm attempting to use AutoFixture
and Autofixture.Idioms
to streamline the testing for guard conditions in a constructor. I'm using the following, familiar, almost boilerplate, method to test:
[TestMethod]
public void DependencyConsumerContainsAGuardCondition ( )
{
var fixture = new Fixture ( );
var assertion = new GuardClauseAssertion ( fixture );
assertion.Verify ( typeof ( DependencyConsumer ).GetConstructors ( ) );
}
I have no problems running the test when the constructor for DependencyConsumer
is a concrete type:
public interface IDependency { }
public class ConcreteDependency : IDependency { }
public class DependencyConsumer
{
public DependencyConsumer(ConcreteDependency dependency)
{
if (dependency == null)
{
throw new ArgumentNullException ( "dependency" );
}
}
}
When, however, I change the type of the constructor parameter to IDependency
, the test fails with the following exception (reformatted for readability)
Test method
AutomatedTestingPlayground.Playground.DependencyConsumerContainsAGuardCondition
threw exception:
Ploeh.AutoFixture.Idioms.GuardClauseException: AutoFixture was unable to
create an instance for parameter "dependency" of method ".ctor".
Method Signature: Void .ctor(AutomatedTestingPlayground.IDependency)
Declaring Type: AutomatedTestingPlayground.DependencyConsumer
Reflected Type: AutomatedTestingPlayground.DependencyConsumer --->
Ploeh.AutoFixture.ObjectCreationException: AutoFixture was unable to
create an instance from AutomatedTestingPlayground.IDependency, most
likely because it has no public constructor, is an abstract or
non-public type.
Request path:
AutomatedTestingPlayground.IDependency
What am I missing in my test setup code? Do I need to mock IDependency
explicitly and provide it as a constructor parameter? Given the stated objectives of AutoFixture--"Zero-friction TDD"--and the frequency with which such constructors occur, I'm not sure why I'd need to mock the constructor parameter when it's an abstract type but not when it's a concrete type.
By default, AutoFixture will only create types that you can
new
up. Abstract types / interfaces can't be created. If you add in one of the various AutoFixture-Mocking assemblies, they can turn AutoFixture into an AutoMocking container. So, when it detects that you're passing abstract types / interfaces, rather than getting confused it will create Mocks for you.AutoMocking versions include: