the*_*per 6 c# integration-testing castle-windsor autofixture
我是AutoFixture的新手,所以我不知道以下想法是否有意义或是合理的事情.我有一个应用程序,我负责集成测试,它大量使用Castle Windsor.为了简化依赖关系管理并使我的测试更像应用程序代码,我一直在我的test initialize方法和using container.Resolve构建Windsor容器来实例化我正在测试的代码.我想摆脱这种方法,因为它在某些情况下限制了我的灵活性.
我想做的是测试看起来像这样:
[Theory]
[Dependency]
public void TestWithDependencies(IThing thing)
{
thing.Hello();
}
Run Code Online (Sandbox Code Playgroud)
为了实现这一目标,我可以执行以下操作:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
这样做确实有效,但我想避免的是需要将每个接口复制到从Windsor容器到AutoFixture IFixture的实现映射.
你应该可以做这样的事情:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
WindsorAdapter位于Customizations
集合中,该集合在AutoFixture的责任树中相当早,因此它有机会处理每个(或大多数)传入请求.如果请求是Type实例且WindsorContainer具有该类型的组件,则适配器将解析类型的工作委托给容器.
否则,它返回一个NoSpecimen
实例,这基本上是AutoFixture发出信号通知这个特定的ISpecimenBuilder无法处理请求的方式.AutoFixture责任树中的其他一些组件则有机会处理请求.