8

我正在使用 AutoFixture 为涉及父对象和复杂子对象的结构生成数据,如下所示:

public class Parent
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Child[] Children { get; set; }
}

public class Child
{
    public string Name { get; set; }
    public int ParentId { get; set; }
}

有没有办法自动将ParentId生成Child对象的属性设置为分配给父对象的 id?现在我的解决方案看起来像这样,这不是很漂亮:

var parent = fixture.Build<Parent>().Without(p => p.Children).CreateAnonymous();
parent.Children = fixture.CreateMany<Child>(10).ToArray();

foreach (var i in parent.Children)
{
    i.ParentId = parent.Id;
}

感觉有更好的方法来做到这一点,我错过了?我研究过创建一个自定义ISpecimenBuilder,但也没有设法以这种方式解决它。

4

1 回答 1

6

AutoFixture 基于一组可能被要求使用的 API 的规则和假设。考虑到它是在没有任何先验知识ChildParent类或给定 API 中的任何其他类型的情况下创建和编译的。它只需要使用公共 API。

将 AutoFixture 视为一个非常笨拙的程序员,他甚至不懂您的语言(甚至不懂英语)。你的 API越简单,使用AutoFixture就越容易。

像这里描述的父/子关系这样的循环引用的问题是它破坏了封装。您需要至少创建一个最初处于无效状态的类实例。很难让 AutoFixture 与这样的 API 一起工作,这主要应该被视为 API 可能从重构中受益的警告信号。

此外,.NET Framework 设计指南建议不要将数组公开为属性 - 特别是可写属性。因此,通过更好的封装设计,API 可能更容易使用,对 AutoFixture 以及您自己和您的同事都是如此。

鉴于上面的 API,我看不出有任何方法可以使它更容易使用。考虑如何移除循环引用并使集合属性只读,这会容易得多。

作为记录,我已经多年没有编写一个带有循环引用的 API,所以很可能避免那些父/子关系。

于 2011-09-06T18:24:07.553 回答