我正在使用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
,但也没有设法以这种方式解决它。
答案 0 :(得分:5)
AutoFixture基于一组有关可能要求使用的API的规则和假设。考虑到它是在没有Child
和Parent
类的任何先验知识或给定API中的任何其他类型的情况下创建和编译的。所有必须使用的是公共API。
将AutoFixture视为一个非常朦胧的程序员,甚至不懂你的语言(甚至不是英语)。您可以制作API的fool-proof越多,使用AutoFixture就越容易。
这里描述的循环引用(例如父/子关系)的问题在于它打破了封装。您最初需要在无效状态下创建至少一个类实例。使用这样的API很难使AutoFixture工作应该主要作为API可能从重构中获益的警告信号。
此外,.NET Framework设计指南建议不要将数组作为属性公开 - 特别是可写属性。因此,使用更好的封装设计,API可能更容易使用,无论是AutoFixture还是您自己和您的同事。
鉴于上面的API,我认为没有任何方法可以使这更容易使用。考虑如何删除循环引用并使集合属性为只读,这将更容易。
为了记录,我多年来没有用循环引用编写API,因此很可能避免这些父/子关系。