3

我想使用 autofixture 创建一个对象图,其中子对象具有对父对象的引用。例如 :

class A
{
  public List<B> Children { get; set; }
}

class B
{
  public A Parent { get; set; }
}

我试图做出一个处理递归的行为,但我不知道如何将父对象作为属性的内容发出。

public class AutoParentOnRecursionBehavior : ISpecimenBuilderTransformation
{
    public ISpecimenBuilder Transform(ISpecimenBuilder builder)
    {
        if (builder == null)
            throw new ArgumentNullException("builder");

        return new RecursionGuard(builder, new AutoParentOnRecursionHandler());
    }
}

public class AutoParentOnRecursionHandler : IRecursionHandler
{
    public object HandleRecursiveRequest(
        object request,
        IEnumerable<object> recordedRequests)
    {
        object handleRecursiveRequest = recordedRequests.First(x => x.Equals(request));
        return ....
    }
}

谢谢。

编辑:我正在考虑一种通用的方式,而不必指定类型 A 和 B 甚至属性 Children。对于包含该对象的属性类型的所有属性,将它们设置为父对象。换句话说,触发递归保护的类型的所有属性都将它们设置为创建层次结构中的最后一个对象。

4

1 回答 1

2

我的回答假设

  1. B.Parentnull如果您直接创建应该是B
  2. B.Parent应该设置为A包含它的实例,如果你创建A.

这可以在使用PostProcessorFor时通过以下相当简单的自定义来实现:

fixture.Customize<B>(c => c.Without(x => x.Parent));
fixture.PostProcessorFor<A>(a => { foreach(var b in a.Children) b.Parent = a; });

一些断言来说明结果:

var b = fixture.Create<B>();
Assert.Null(b.Parent);

var a = fixture.Create<A>();
Assert.True(a.Children.All(b => ReferenceEquals(b.Parent, a)));
于 2013-06-25T14:51:05.640 回答