And*_*erd 27 unit-testing castle-windsor
我试图在我的自动化测试中使用Castle Windsor,如下所示:
每次测试:
Setup()函数创建一个Windsor容器,注册每个组件的默认实现Test函数通过该方法访问组件IWindsorContainer.Resolve<T>,并测试它们的行为TearDown()函数处理Windsor容器(以及任何创建的组件)例如,我可能有15个测试访问组件,这些组件间接导致组件的创建IMediaPlayerProxyFactory.该SetUp函数注册了一个足够好的实现IMediaPlayerProxyFactory,所以我没有在15个测试中的每个测试中注册这个的维护负担.
但是,我现在正在编写测试Test_MediaPlayerProxyFactoryThrowsException,确认我的系统优雅地处理IMediaPlayerProxyFactory组件中的错误.在测试方法中,我创建了我的特殊模拟实现,现在我想将它注入到框架中:
this.WindsorContainer.Register(
Component.For<IMediaPlayerProxyFactory>()
.Instance(mockMediaPlayerProxyFactory)
);
Run Code Online (Sandbox Code Playgroud)
但温莎抛出一条Castle.MicroKernel.ComponentRegistrationException消息,"已经有一个有这个名字的组件."
有什么方法可以让我mockMediaPlayerProxyFactory成为默认实例IMediaPlayerProxyFactory,丢弃已经注册的组件?
Container.Register(
Classes.FromThisAssembly()
.BasedOn<IEmptyService>()
.WithService.Base()
.ConfigureFor<EmptyServiceA>(c => c.IsDefault()));
Run Code Online (Sandbox Code Playgroud)
ConfigureFor是一种BasedOnDescriptor类的方法.在我的情况下,我没有使用FromDescriptor或BasedOnDescriptor.
And*_*erd 66
要创建覆盖实例,您需要做两件事:
IsDefault方法为了让这个例子起作用:
this.WindsorContainer.Register(
Component.For<IMediaPlayerProxyFactory>()
.Instance(mockMediaPlayerProxyFactory)
.IsDefault()
.Named("OverridingFactory")
);
Run Code Online (Sandbox Code Playgroud)
因为我计划在许多测试中使用这个覆盖模式,所以我创建了自己的扩展方法:
public static class TestWindsorExtensions
{
public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class
{
return componentRegistration
.Named(Guid.NewGuid().ToString())
.IsDefault();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,该示例可以简化为:
this.WindsorContainer.Register(
Component.For<IMediaPlayerProxyFactory>()
.Instance(mockMediaPlayerProxyFactory)
.OverridesExistingRegistration()
);
Run Code Online (Sandbox Code Playgroud)
3.1版介绍了该IsFallback方法.如果我注册了所有初始组件IsFallback,那么任何新注册都将自动覆盖这些初始注册.如果功能在当时可用,我会走这条路.
https://github.com/castleproject/Windsor/blob/master/docs/whats-new-3.1.md#fallback-components