2

I have a class that conceptually looks like this:

public class Entity
{
    private readonly List<double> _values = new List<double>();

    ...

    public List<double> Values
    {
        get
        {
            return _values;
        }
    }
}

In a unit test, I want to use AutoFixture to provide a list of random entities:

var entities = this.fixture.CreateMany<Entity>().ToList();

However, no autogenerated values are added to the Values property of the Entity objects, as I would have expected (hoped...). I have tried to change the list of values to not being readonly and add a setter to the Values property, which solves the problem, but isn't there a better alternative to this?

Lars Michael
  • 693
  • 9
  • 19
  • see https://stackoverflow.com/questions/20808755/specifying-readonly-property-values-via-ctor-args-when-instantiating-immuta/57202205#57202205 – Fabio Marreco Jul 25 '19 at 12:40

2 Answers2

4

AutoFixture doesn't fill read-only collections, but you can ask it to do so:

var entity = fixture.Create<Entity>();
fixture.AddManyTo(entity.Values);
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
2

When I discovered this limitation, I went ahead and created an AutoFixture extension to do just this: Murph.AutoFixture.AutoReadOnlyCollectionProperties. Publicly available on nuget.org as well.

While building an object, for any public, read-only property or field whose type implements ICollection<T>, it will use the fixture to create a list of T and then call the collection's Add() method for each one. It will respect the fixture's OmitAutoProperties setting, and also provides an extension method, WithoutEx() that emulates the built-in Without() (which won't work with read-only properties or fields).

Usage is as easy as you'd expect:

fixture.Customize( new AutoReadOnlyCollectionPropertiesCustomization() );
fixture.Customize< Model >( c => c.WithoutEx( m => m.Collection ) );
Kurt Hutchinson
  • 2,959
  • 23
  • 30