Lars Michael
Lars Michael

Reputation: 693

How do I auto-generate objects containing a readonly list using AutoFixture?

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?

Upvotes: 2

Views: 2939

Answers (2)

Kurt Hutchinson
Kurt Hutchinson

Reputation: 3069

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 ) );

Upvotes: 2

Mark Seemann
Mark Seemann

Reputation: 233150

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

var entity = fixture.Create<Entity>();
fixture.AddManyTo(entity.Values);

Upvotes: 5

Related Questions