Consider the following way to represent family members:
public abstract class Human { }
public abstract class Child : Human
{
public ICollection<Parent> Parents { get; set; }
}
public abstract class Parent : Human
{
public ICollection<Child> Children { get; set; }
}
public class Son : Child { }
public class Daughter : Child { }
public class Mum : Parent { }
public class Dad : Parent { }
Now, I want AutoFixture
to generate a Parent
, chosen randomly between Mum
and Dad
, and where the children are randomly chosen between Son
and Daughter
. I also want it to omit recursion, so if it's coming from Parent
and generating a Child
, it can omit the link back to Parent
.
I tried the following customization:
var fixture = new Fixture();
fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList()
.ForEach(b => fixture.Behaviors.Remove(b));
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
var random = new Random();
fixture.Register<Parent>(() =>
{
switch (random.Next(1, 2))
{
case 1:
return fixture.Create<Mum>();
case 2:
return fixture.Create<Dad>();
default:
throw new NotImplementedException();
}
});
fixture.Register<Child>(() =>
{
switch (random.Next(1, 2))
{
case 1:
return fixture.Create<Son>();
case 2:
return fixture.Create<Daughter>();
default:
throw new NotImplementedException();
}
});
fixture.Create<Parent>();
but it throws an InvalidCastException
(see below).
Is there a way to configure AutoFixture so that it considers Parent -> Child -> Parent
recursion, even though it actually randomly selects an appropriate subclass for each instance?
Unhandled Exception: AutoFixture.ObjectCreationExceptionWithPath: AutoFixture was unable to
create an instance from AutoFixtureAbstractTrees.Parent because creation unexpectedly
failed with exception. Please refer to the inner exception to investigate the root cause of
the failure.
Request path:
AutoFixtureAbstractTrees.Mum
System.Collections.Generic.ICollection`1[AutoFixtureAbstractTrees.Child] Children
System.Collections.Generic.ICollection`1[AutoFixtureAbstractTrees.Child]
System.Collections.Generic.List`1[AutoFixtureAbstractTrees.Child]
System.Collections.Generic.IEnumerable`1[AutoFixtureAbstractTrees.Child] collection
System.Collections.Generic.IEnumerable`1[AutoFixtureAbstractTrees.Child]
AutoFixtureAbstractTrees.Child
AutoFixtureAbstractTrees.Son
System.Collections.Generic.ICollection`1[AutoFixtureAbstractTrees.Parent] Parents
System.Collections.Generic.ICollection`1[AutoFixtureAbstractTrees.Parent]
System.Collections.Generic.List`1[AutoFixtureAbstractTrees.Parent]
System.Collections.Generic.IEnumerable`1[AutoFixtureAbstractTrees.Parent] collection
System.Collections.Generic.IEnumerable`1[AutoFixtureAbstractTrees.Parent]
AutoFixtureAbstractTrees.Parent
Inner exception messages:
System.InvalidCastException: Unable to cast object of type
'AutoFixture.Kernel.OmitSpecimen' to type 'AutoFixtureAbstractTrees.Mum'.