Использовать значение родительского свойства при создании сложного дочернего элемента в AutoFixture - PullRequest
8 голосов
/ 06 сентября 2011

Я использую 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 идентификатор, назначенный родительскому объекту? Прямо сейчас мое решение выглядит так, что не очень красиво:

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, но так и не смог его решить.

1 Ответ

5 голосов
/ 06 сентября 2011

Автофиксирование основано на наборе правил и предположений об API, с которым его могут попросить работать. Учтите, что он был создан и скомпилирован без какого-либо предварительного знания классов Child и Parent или любых других типов в данном API. Все, с чем он должен работать - это общедоступный API.

Подумайте об AutoFixture как о очень слабом программисте, который даже не понимает ваш язык (даже английский). Чем больше надежных вы можете сделать свой API, тем проще будет использовать AutoFixture с ним.

Проблема с циклическими ссылками, такими как описанные здесь отношения Родитель / Дочерний, заключается в том, что они нарушают инкапсуляцию. Вам нужно будет создать хотя бы один из экземпляров класса изначально в недопустимом состоянии. То, что AutoFixture трудно использовать для работы с таким API, в основном следует рассматривать как предупреждение о том, что API может выиграть от рефакторинга.

Кроме того, в Руководстве по проектированию .NET Framework не рекомендуется указывать массивы как свойства, в частности, свойства, доступные для записи. Таким образом, благодаря более качественному инкапсулированному дизайну API-интерфейс будет намного проще работать как для AutoFixture, так и для вас и ваших коллег.

Учитывая API, приведенный выше, я не вижу способа, с которым можно было бы сделать работу намного проще. Подумайте, как удалить циклическую ссылку и сделать свойства коллекции доступными только для чтения, и это будет намного проще.

Для справки, я не писал API с циклической ссылкой в ​​течение многих лет, поэтому вполне возможно избежать таких отношений между родителями и детьми.

...