6

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

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

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

为此,我可以执行以下操作:

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 的实现映射。

4

1 回答 1

6

你应该能够做这样的事情:

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 位于Customizations集合中,该集合在 AutoFixture 的责任树中相当早,因此它有机会处理每个(或大多数)传入请求。如果请求是 Type 实例并且 WindsorContainer 具有该类型的组件,则适配器将解析该类型的工作委托给容器。

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

于 2012-08-14T19:01:16.403 回答