Use value of a parent property when creating a complex child in AutoFixture

我只是一个虾纸丫 提交于 2019-11-26 23:28:30

问题


I'm using AutoFixture to generate data for a structure involving a parent object and complex child objects, like this:

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

Is there a way to automatically set the property ParentId of the generated Child object to the id assigned to the parent? Right now my solution looks like this, which isn't very pretty:

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

It feels like there's a better way to do this that I am missing? I looked into creating a custom ISpecimenBuilder but didn't manage to solve it that way either.


回答1:


AutoFixture is based on a set of rules and assumptions about the API it may be asked to work with. Consider that it's been created and compiled without any prior knowledge of the Child and Parent classes, or any other types in a given API. All it has to work with is the public API.

Think of AutoFixture as a very dim programmer who doesn't even understand your language (not even English). The more fool-proof you can make your API, the easier it will be to use AutoFixture with it.

The problem with circular references like the Parent/Child relationship described here is that it breaks encapsulation. You'll need to create at least one of the class instances initially in an invalid state. That it's difficult to make AutoFixture work with such an API should mainly be taken as a warning sign that the API might benefit from refactoring.

Additionally, the .NET Framework Design Guidelines recommends against exposing arrays as properties - particularly writable properties. Thus, with a better encapsulated design, the API might be much easier to work with, both for AutoFixture and yourself and your colleagues.

Given the API above, I don't see any way this can be made much easier to work with. Consider how to remove the circular reference and make collection properties read-only, and it will be much easier.

For the record, I haven't written an API with a circular reference for years, so it's quite possible to avoid those Parent/Child relations.



来源:https://stackoverflow.com/questions/7319984/use-value-of-a-parent-property-when-creating-a-complex-child-in-autofixture

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!