Preventing Autofixture from filling child collections
autofixture, c#
Solution
Here's one way to do it.
Start by implementing a SpecimenBuilder that tells AutoFixture to skip assigning a value for collection property:
public class CollectionPropertyOmitter : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var pi = request as PropertyInfo;
if (pi != null
&& pi.PropertyType.IsGenericType
&& pi.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>))
return new OmitSpecimen();
return new NoSpecimen(request);
}
}
Then encapsulate that in a Customization:
public class DoNotFillCollectionProperties : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new CollectionPropertyOmitter());
}
}
The following tests now pass:
[Fact]
public void CreatePersonWithoutFillingCollectionProperty()
{
var fixture = new Fixture().Customize(new DoNotFillCollectionProperties());
var actual = fixture.Create<Person>();
Assert.Null(actual.OtherClasses);
}
[Fact]
public void CreateManyStillWorks()
{
var fixture = new Fixture().Customize(new DoNotFillCollectionProperties());
var actual = fixture.CreateMany<Person>();
Assert.NotEmpty(actual);
}
[Fact]
public void CreatListStillWorks()
{
var fixture = new Fixture().Customize(new DoNotFillCollectionProperties());
var actual = fixture.Create<List<Person>>();
Assert.NotEmpty(actual);
}
[Fact]
public void CreateCollectionStillWorks()
{
var fixture = new Fixture().Customize(new DoNotFillCollectionProperties());
var actual = fixture.Create<ICollection<Person>>();
Assert.NotEmpty(actual);
}
Problem
I'm using the latest version of Autofixture, and I'd like to prevent it from filling automatically child collections. For example, I have a class Person that has a List property. I want all properties filled, except the list. I tried using this customization : ``` public class RemoveMultiples : ICustomization { public void Customize(IFixture fixture) { fixture.Customizations .OfType<FilteringSpecimenBuilder>() .Where(x => x.Specification is DictionarySpecification) .ToList().ForEach(c => fixture.Customizations.Remove(c)); fixture.Customizations .OfType<FilteringSpecimenBuilder>() .Where(x => x.Specification is CollectionSpecification) .ToList().ForEach(c => fixture.Customizations.Remove(c)); fixture.Customizations .OfType<FilteringSpecimenBuilder>() .Where(x => x.Specification is HashSetSpecification) .ToList().ForEach(c => fixture.Customizations.Remove(c)); fixture.Customizations .OfType<FilteringSpecimenBuilder>() .Where(x => x.Specification is ListSpecification) .ToList().ForEach(c => fixture.Customizations.Remove(c)); } } ``` But it also prevents me from using `.CreateMany()`. edit: I can use `.CreateMany(3)` and it works. Is there a setting somewhere that could let me autofill collections only when I need to? edit2: Class person should look like this: ``` [Serializable] public class Person { private ICollection<OtherClass> _otherClasses; private string _something; public virtual ICollection<OtherClass> OtherClasses { get { return _otherClasses; } set { _otherClasses = value; } } } ``` Note that it's not always a `Collection`, but sometimes `IList` Note2: I just realized that someone also removed the Customization for `IEnumerable` hence why the `CreateMany()` doesn't create anything.