Я только что начал использовать AutoFixture и имею эту полукомплексную структуру данных, для которой я хотел бы создать образец. В тестах, с которыми я работаю, меня не слишком беспокоит содержание структуры данных. Я просто хочу разумные значения по умолчанию.
Часть этой структуры данных является рекурсивным деревом. Более конкретно, один класс содержит коллекцию некоторого другого класса, который содержит список самих детей. Что-то похожее на:
public class A
{
private IEnumerable<B> bNodes;
public A(IEnumerable<B> bNodes)
{
this.bNodes = bNodes;
}
}
public class B
{
private IEnumerable<B> children;
public B(IEnumerable<B> children)
{
this.children = children;
}
}
Предположим, что я не могу легко изменить эту структуру по разным причинам.
Если я попрошу, чтобы мое устройство создало A ThrowingRecursionBehavior, он начнет лаять о том, что B является рекурсивным.
Если я заменил ThrowingRecursionBehavior на OmitOnRecursionBehavior, я получаю исключение ObjectCreateException.
Если я попробую что-то вроде: fixture.Inject(Enumerable.Empty()); Я получаю "Элемент с тем же ключом уже добавлен" из DictionaryFiller. То же самое происходит, если я заменю ThrowingRecursionBehavior на NullRecursionBehavior.
Есть несколько вещей, которые я хотел бы сделать.
- Что было бы лучшим способом создать образец A с пустым списком Bs?
- Что было бы лучшим способом создать образец A с несколькими Bs, содержащими несколько B-детей с несколькими детьми (маленькое дерево)?
Для моего последнего желания было бы неплохо указать некоторую глубину рекурсии, после которой был использован Enumerable.Empty(или массив нулевого размера /List или даже null). Я знаю, что AutoFixture очень гибко расширяется. Поэтому, я полагаю, должно быть возможно создать какой-то экземпляр-строитель, который сделает именно это. На самом деле я попытаюсь обмануть себя с помощью специального ISpecimenBuilder, но, возможно, у кого-то есть более разумное решение. Например, имеет смысл модифицировать эту строку в RecursionGuard:
public object Create(object request, ISpecimenContext context)
{
if (this.monitoredRequests.Any(x => this.comparer.Equals(x, request)))
...
к
public object Create(object request, ISpecimenContext context)
{
if (this.monitoredRequests.Count(x => this.comparer.Equals(x, request)) > maxAllowedRecursions)
...