自动固定-新列表中的基础属性来自先前构建的属性

时间:2019-03-07 23:47:04

标签: c# .net unit-testing testing autofixture

我想我缺少了一些东西,但是我想做的是这样:

我有两个用C#代码表示的数据库实体。一个是另一个的孩子,因此该孩子包含一个应引用父母ID的字段。

父类如下

public class Product
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public decimal Price { get; set; }

    public decimal DeliveryPrice { get; set; }
}

子类如下:

public class ProductOption
{
    public Guid Id { get; set; }

    public Guid ProductId { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }
}

我这样创建了一个随机的“父母”列表:

var products = fixture.CreateMany<Product>(5).ToList();

然后我想要创建10个子对象,并从AutoFixture创建的产品列表中随机给它们一个ProductId。所以我尝试了这个:

var rand = new Random();
var options = fixture.Build<ProductOption>()
    .With(option => option.ProductId, products[rand.Next(0, 5)].Id)
    .CreateMany(10)
    .ToList();

几乎 有效,但是我发现所有ProductId都是同一个,因此显然只击过rand.Next一次。

我正在做的事情甚至可能/建议吗?

1 个答案:

答案 0 :(得分:3)

当我为属性提供值时,我希望所有具有相同构建器/夹具的实例都将提供值。
因此,您注意到的是期望的行为。

您可以提供一个“工厂”来代替已生成的值,该“工厂”将在实例创建期间为属性生成值。
最新的Autofixture版本为.With方法引入了重载,该方法接受一个函数作为参数。

var rand = new Random();
Func<Guid> pickProductId = () => products[rand.Next(0, 5)].Id;

var options = 
    fixture.Build<ProductOption>()
           .With(option => option.ProductId, pickProductId)
           .CreateMany(10)
           .ToList();

// Prove
options.Select(o => o.ProductId).ToHashSet().Should().HaveCountGreaterThan(1); // Pass Ok