Is there any possibility to create a collection with a unique property in AutoFixture
? For instance, I would like to create a collection of:
public class Foo {
public int Id {get; set;}
public string Name {get;set;}
}
with unique Id
. It would look something like this:
var fixture = new Fixture();
fixture
.Build<Foo>()
.WithUnique((foo) => foo.Id)
.CreateMany(20);
I know it is possible to do this through customization, but I think it's quite common scenario so might be AutoFixture
has something ready for this?
Autofixture by default generates unique values for properties. So you don't have to specify which property should be unique - instead, specify a non-unique value for other property:
// with AutoFixture.SeedExtensions
fixture.Build<Foo>().With(f => f.Name, fixture.Create("Name")).CreateMany(20)
Note if you want to ensure non-unique values for other properties (having only Id unique), then you can create simple extensions for IPostprocessComposer
which provide a set of possible values for the property:
public static IPostprocessComposer<T> With<T, TProperty>(
this IPostprocessComposer<T> composer,
Expression<Func<T, TProperty>> propertyPicker,
IEnumerable<TProperty> possibleValues) =>
composer.With(propertyPicker, possibleValues.ToArray());
public static IPostprocessComposer<T> With<T, TProperty>(
this IPostprocessComposer<T> composer,
Expression<Func<T, TProperty>> propertyPicker,
params TProperty[] possibleValues)
{
var rnd = new Random();
return composer.With(
propertyPicker,
() => possibleValues[rnd.Next(0, possibleValues.Length)]);
}
Usage is simple - following code creates list of foos with only two different values for name, and three different values for some integer property:
fixture.Build<Foo>()
.With(f => f.SomeIntegerProperty, 10, 20, 50)
.With(f => f.Name, fixture.CreateMany<string>(2))
.CreateMany(20);