使用AutoFixture对使用Castle Windsor的应用程序进行集成测试的技术 [英] Technique for using AutoFixture to integration test an application using Castle Windsor

查看:57
本文介绍了使用AutoFixture对使用Castle Windsor的应用程序进行集成测试的技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是AutoFixture的新手,所以我不知道以下想法是否有意义或合理。我有一个负责集成测试的应用程序,它大量使用了城堡温莎城堡。为了简化依赖关系管理并使我的测试更像应用程序代码,我已经在我的测试初始化​​方法和using容器中构建了Windsor容器。决心实例化我正在测试的代码。我想放弃这种方法,因为它在某些情况下限制了我的灵活性。

I'm new to AutoFixture, so I don't know if the following idea is going to make sense or be a reasonable thing to do. I've got an application that I'm in charge of integration testing, and it makes heavy use of Castle Windsor. To simplify dependency management and make my tests more like the application code, I've been building the Windsor container in my test initialize method and the using container.Resolve to instantiate the code I'm testing. I'd like to move away from that approach since it has limited my flexibility in certain situations.

我要做的是进行如下所示的测试:

What I'd like to do is have tests that look something like this:

[Theory]
[Dependency]
public void TestWithDependencies(IThing thing)
{
    thing.Hello();
}

要做到这一点,我可以执行以下操作:

To make this happen, I can do the following:

public sealed class DependencyAttribute : AutoDataAttribute
{
    public DependencyAttribute()
        : base(new Fixture().Customize(new WindsorCustomization()))
    {
    }
}

public class WindsorCustomization : ICustomization
{
    public WindsorCustomization()
    {
        // build container here using SUT installers
    }

    public void Customize(IFixture fixture)
    {
        fixture.Inject<IThing>(new Thing());
    }
}

这样做确实可行,但我想要的是为了避免需要将每个接口复制到实现映射,这些映射从Windsor容器复制到AutoFixture IFixture。

Doing this does work, but what I'd like to avoid is needing to copy every interface to implementation mapping from the Windsor container into the AutoFixture IFixture.

推荐答案

您应该可以执行以下操作:

You should be able to do something like this:

public class WindsorCustomization : ICustomization
{
    private readonly IWindsorContainer container;

    public WindsorCustomization()
    {
        // build this.container here using SUT installers
    }

    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Add(new WindsorAdapter(this.container));
    }
}

public WindsorAdapter : ISpecimenBuilder
{
    private readonly IWindsorContainer container;

    public WindsorAdapter(IWindsorContainer container)
    {
        this.container = container;
    }

    public object Create(object request, ISpecimenContext context)
    {
        var t = request as Type;
        if (t == null || !this.container.Kernel.HasComponent(t))
            return new NoSpecimen(request);

        return this.container.Resolve(t);                
    }
}

WindsorAdapter位于自定义集合,这在AutoFixture的责任树中还很早,因此它有机会处理每个(或大多数)传入的请求。如果请求是Type实例,并且WindsorContainer具有该类型的组件,则适配器将解析类型的工作委托给容器。

The WindsorAdapter sits in the Customizations collection, which is fairly early in AutoFixture's Tree of Responsibility, so it gets a chance to handle every (or most) incoming requests. If the request is a Type instance and the WindsorContainer has a component for that type, the adapter delegates the work of resolving the type to the container.

否则,它将返回一个 NoSpecimen 实例,这基本上是AutoFixture发出信号的信号,该信号表明此特定ISpecimenBuilder无法处理该请求。然后,自动修复责任树中的其他一些组件将有机会处理请求。

Otherwise, it returns a NoSpecimen instance, which is basically AutoFixture's way of signaling that this particular ISpecimenBuilder couldn't handle the request. Some other component in the AutoFixture Tree of Responsibility then gets the chance to handle the request.

这篇关于使用AutoFixture对使用Castle Windsor的应用程序进行集成测试的技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆