gpt4 book ai didi

c# - 如何在 AutoFixture 中设置更复杂(类似 IoC)的注册

转载 作者:行者123 更新时间:2023-11-30 16:53:11 25 4
gpt4 key购买 nike

使用 AutoFixture 时是否可以在集成测试中重用生产 IoC 容器注册?

问题是如果依赖项未注册并注入(inject)“真实”数据库相关依赖项,我需要以下夹具设置来注入(inject)模拟

var fixture = new Fixture().WithMocks().WithRealDatabase()

我试过的解决方案

internal static Fixture WithMocks(this Fixture fixture)
{
fixture.Customize(new AutoMoqCustomization());
}

internal static Fixture WithRealDatabase(this Fixture fixture)
{
var containerBuilder = new Autofac.ContainerBuilder();
...
containerBuilder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
containerBuilder.RegisterGeneric(typeof(Repository<>)).AsImplementedInterfaces()
containerBuilder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
...
fixture.Customizations.Add(new ContainerSpecimenBuilder(containerBuilder.Build()));
}

internal class ContainerSpecimenBuilder : ISpecimenBuilder
{
private readonly IContainer container;

public ContainerSpecimenBuilder(IContainer container)
{
this.container = container;
}

public object Create(object request, ISpecimenContext context)
{
var seededRequest = request as SeededRequest;

if (seededRequest == null)
{
return new NoSpecimen(request);
}

var result = this.container.ResolveOptional(seededRequest.Request as Type);
return result ?? new NoSpecimen(request);
}
}

但这种方法的问题是 container.Resolve 不会考虑已在 AutoFixture 中注册的依赖项。

是否有其他方法可以解决这个问题以进行更复杂的注册?

最佳答案

一般方法看起来不错,但您应该将 ContainerSpecimenBuilder 添加到 ResidueCollectors 而不是 Customizations:

fixture.ResidueCollectors.Add(new ContainerSpecimenBuilder(containerBuilder.Build()));

AutoMoqCustomization 还向 ResidueCollectors 添加了一个节点,因此您可能需要对特定的顺序进行一些试验,以弄清楚如何使其表现得如您所愿表现。 The ordering matters .

有关 CustomizationsResidueCollectors 之间差异的更多信息,请参阅 AutoFixture architecture documentation .


ContainerSpecimenBuilder 的一个稍微简单(并且更安全?)的实现可能只是直接处理对 Type 实例的请求,而不是对 SeededRequest 的请求,因为几乎所有的 SeededRequest 值都被转发到对 Type 对象的请求:

internal class ContainerSpecimenBuilder : ISpecimenBuilder
{
private readonly IContainer container;

public ContainerSpecimenBuilder(IContainer container)
{
this.container = container;
}

public object Create(object request, ISpecimenContext context)
{
var t = request as Type;

if (t == null)
return new NoSpecimen(request);

var result = this.container.ResolveOptional(t);
return result ?? new NoSpecimen(request);
}
}

关于c# - 如何在 AutoFixture 中设置更复杂(类似 IoC)的注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31740092/

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