首页 > 解决方案 > 具有独特属性的 AutoFixture 构建集合

问题描述

有没有可能在 中创建具有独特属性的集合AutoFixture?例如,我想创建一个集合:

public class Foo {
 public int Id {get; set;}
 public string Name {get;set;}
}

具有独特性Id。它看起来像这样:

var fixture = new Fixture();

fixture
 .Build<Foo>()
 .WithUnique((foo) => foo.Id)
 .CreateMany(20);

我知道可以通过定制来做到这一点,但我认为这是很常见的情况,所以可能AutoFixture有什么准备好了吗?

标签: c#.netautofixture

解决方案


默认情况下,Autofixture 会为属性生成唯一值。因此,您不必指定哪个属性应该是唯一的 - 相反,为其他属性指定一个非唯一值:

// with AutoFixture.SeedExtensions
fixture.Build<Foo>().With(f => f.Name, fixture.Create("Name")).CreateMany(20)

请注意,如果您想确保其他属性的值不唯一(只有 Id 唯一),那么您可以创建简单的扩展,IPostprocessComposer为其提供一组可能的属性值:

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

用法很简单 - 以下代码创建 foos 列表,其中只有两个不同的 name 值和三个不同的值用于某些整数属性:

fixture.Build<Foo>()
    .With(f => f.SomeIntegerProperty, 10, 20, 50)
    .With(f => f.Name, fixture.CreateMany<string>(2))
    .CreateMany(20);

推荐阅读