gpt4 book ai didi

unit-testing - 如何为特定类自定义 AutoFixture 行为

转载 作者:行者123 更新时间:2023-12-04 04:09:42 25 4
gpt4 key购买 nike

我需要启用 AutoFixture 来创建具有循环引用的类型实例(来自第三方提供的 API)。为此,我可以删除默认的 ThrowingRecursionBehavior如下所示:

public class RecursiveObjectCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Behaviors.OfType<ThrowingRecursionBehavior>()
.ToList()
.ForEach(b => fixture.Behaviors.Remove(b));
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
}
}

但是,我知道这将删除 ThrowingRecursionBehavior通过属性应用自定义时的所有类型。如何将修改后的行为限制为仅适用于特定类型?

最佳答案

您必须为此创建自定义行为。

这里有一些事情要开始:

public class OmitOnRecursionForRequestBehavior : ISpecimenBuilderTransformation
{
private const int DefaultRecursionDepth = 1;
private readonly int recursionDepth;
private readonly object request;

public OmitOnRecursionForRequestBehavior(object request)
: this(request, DefaultRecursionDepth)
{
}

public OmitOnRecursionForRequestBehavior(
object request,
int recursionDepth)
{
if (request == null)
throw new ArgumentNullException("request");
if (recursionDepth < 1)
throw new ArgumentOutOfRangeException(
"recursionDepth",
"Recursion depth must be greater than 0.");

this.recursionDepth = recursionDepth;
this.request = request;
}

public ISpecimenBuilder Transform(ISpecimenBuilder builder)
{
if (builder == null)
throw new ArgumentNullException("builder");

return new RecursionGuard(
builder,
new RecursionForRequestHandler(
request,
new OmitOnRecursionHandler(),
builder),
recursionDepth);
}
}

public class RecursionForRequestHandler : IRecursionHandler
{
private readonly object request;
private readonly IRecursionHandler handlerForRequest;
private readonly ISpecimenBuilder handler;

public RecursionForRequestHandler(
object request,
IRecursionHandler handlerForRequest,
ISpecimenBuilder handler)
{
if (request == null)
throw new ArgumentNullException("request");
if (handlerForRequest == null)
throw new ArgumentNullException("handlerForRequest");
if (handler == null)
throw new ArgumentNullException("handler");

this.request = request;
this.handlerForRequest = handlerForRequest;
this.handler = handler;
}

public object HandleRecursiveRequest(
object request,
IEnumerable<object> recordedRequests)
{
if (this.request.Equals(request))
return handlerForRequest.HandleRecursiveRequest(
request,
recordedRequests);

return handler.Create(request, new SpecimenContext(handler));
}
}

这是你将如何使用它:
fixture.Behaviors.Add(new OmitOnRecursionForRequestBehavior(typeof(MyType)));
fixture.Behaviors.Add(new OmitOnRecursionForRequestBehavior(typeof(AnotherType)));

请注意,您不会删除 ThrowingRecursionBehavior因为它将用于保护其他请求,否则为 StackOverflowException将被抛出。

但是,如果您指定 recursionDepth大于 1,您必须删除 ThrowingRecursionBehavior并创建一个大于或等于 recursionDepth 的自定义.
public class DepthThrowingRecursionBehavior : ISpecimenBuilderTransformation
{
private readonly int recursionDepth;

public DepthThrowingRecursionBehavior(int recursionDepth)
{
if (recursionDepth < 1)
throw new ArgumentOutOfRangeException(
"recursionDepth",
"Recursion depth must be greater than 0.");

this.recursionDepth = recursionDepth;
}

public ISpecimenBuilder Transform(ISpecimenBuilder builder)
{
if (builder == null)
throw new ArgumentNullException("builder");

return new RecursionGuard(
builder,
new ThrowingRecursionHandler(),
recursionDepth);
}
}
fixture.Behaviors.OfType<ThrowingRecursionBehavior>()
.ToList()
.ForEach(b => fixture.Behaviors.Remove(b));
fixture.Behaviors.Add(new DepthThrowingRecursionBehavior(2));
fixture.Behaviors.Add(new OmitOnRecursionForRequestBehavior(typeof(MyType), 2));
fixture.Behaviors.Add(new OmitOnRecursionForRequestBehavior(typeof(AnotherType), 1));

关于unit-testing - 如何为特定类自定义 AutoFixture 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31855842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com