模拟 WindsorContainer 以测试 ComponentRegistration
Mocking WindsorContainer to test the ComponentRegistration
我正在使用 Castle.Windsor 4.1.1 并且我有这样的注册:
container.Register(Component.For<IMessageMappingManager>().ImplementedBy<MessageMappingManager>());
现在我想测试注册是否正常,因此我使用 Moq 4.10.0 模拟了一个 _container:
_container = new Mock<IWindsorContainer>();
现在我想这样测试注册:
_container.Verify(f => f.Register(Component.For<IMessageMappingManager>().ImplementedBy<MessageMappingManager>()), Times.Once);
或者像这样:
_container.Verify(f=>f.Register(It.IsAny<ComponentRegistration<IMessageMappingManager>().ImplementedBy<MessageMappingManager>()>()), Times.Once);
但其中 none 有效。
有人可以帮忙吗?
提前致谢。
您答案中的单元测试没有测试任何内容。第一个问题是您正在模拟被测系统。
整点来测试你对被测系统的执行情况。
那么您唯一的测试就是对模拟对象的调用发生了。验证实际注册是否发生非常容易。
此示例使用安装程序,因为我使用它们来清理大量注册码。
public class EmailInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For(typeof(IResolveApplicationPath))
.ImplementedBy(typeof(ApplicationPathResolver))
.LifeStyle.PerWebRequest);
container
.Register(Component.For(typeof(IGenerateEmailMessage)).ImplementedBy(typeof(EmailMessageGenerator))
.LifeStyle
.PerWebRequest);
container
.Register(Component.For(typeof(ISendEmail)).ImplementedBy(typeof(EmailSender))
.LifeStyle
.PerWebRequest);
container.Register(
Component.For<NotificationConfigurationSection>()
.UsingFactoryMethod(
kernel =>
kernel.Resolve<IConfigurationManager>()
.GetSection<NotificationConfigurationSection>("notificationSettings")));
}
}
然后我的测试看起来像
public class WhenInstallingEmailComponents : SpecificationBase
{
private IWindsorContainer _sut;
protected override void Given()
{
_sut = new WindsorContainer();
}
protected override void When()
{
_sut.Install(new EmailInstaller());
}
[Then]
public void ShouldConfigureEmailSender()
{
var handler = _sut
.GetHandlersFor(typeof(ISendEmail))
.Single(imp => imp.ComponentModel.Implementation == typeof(EmailSender));
Assert.That(handler, Is.Not.Null);
}
[Then]
public void ShouldConfigureEmailGenerator()
{
var handler = _sut
.GetHandlersFor(typeof(IGenerateEmailMessage))
.Single(imp => imp.ComponentModel.Implementation == typeof(EmailMessageGenerator));
Assert.That(handler, Is.Not.Null);
}
}
}
这里是 GetHandlersFor 扩展方法
public static class WindsorTestingExtensions
{
public static IHandler[] GetAllHandlers(this IWindsorContainer container)
{
return container.GetHandlersFor(typeof(object));
}
public static IHandler[] GetHandlersFor(this IWindsorContainer container, Type type)
{
return container.Kernel.GetAssignableHandlers(type);
}
public static Type[] GetImplementationTypesFor(this IWindsorContainer container, Type type)
{
return container.GetHandlersFor(type)
.Select(h => h.ComponentModel.Implementation)
.OrderBy(t => t.Name)
.ToArray();
}
}
我使用基础 class SpecficationBase 让我的单元测试读起来像 BDD 风格的测试,但你应该能够理解发生了什么。
- 实例化你的容器
- 调用安装程序来注册您的组件。
- 检查容器中的接口实现类型。
这是 Castle 项目中有关如何测试您的注册码的好文章 link。
我正在使用 Castle.Windsor 4.1.1 并且我有这样的注册:
container.Register(Component.For<IMessageMappingManager>().ImplementedBy<MessageMappingManager>());
现在我想测试注册是否正常,因此我使用 Moq 4.10.0 模拟了一个 _container:
_container = new Mock<IWindsorContainer>();
现在我想这样测试注册:
_container.Verify(f => f.Register(Component.For<IMessageMappingManager>().ImplementedBy<MessageMappingManager>()), Times.Once);
或者像这样:
_container.Verify(f=>f.Register(It.IsAny<ComponentRegistration<IMessageMappingManager>().ImplementedBy<MessageMappingManager>()>()), Times.Once);
但其中 none 有效。
有人可以帮忙吗?
提前致谢。
您答案中的单元测试没有测试任何内容。第一个问题是您正在模拟被测系统。
整点来测试你对被测系统的执行情况。
那么您唯一的测试就是对模拟对象的调用发生了。验证实际注册是否发生非常容易。
此示例使用安装程序,因为我使用它们来清理大量注册码。
public class EmailInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For(typeof(IResolveApplicationPath))
.ImplementedBy(typeof(ApplicationPathResolver))
.LifeStyle.PerWebRequest);
container
.Register(Component.For(typeof(IGenerateEmailMessage)).ImplementedBy(typeof(EmailMessageGenerator))
.LifeStyle
.PerWebRequest);
container
.Register(Component.For(typeof(ISendEmail)).ImplementedBy(typeof(EmailSender))
.LifeStyle
.PerWebRequest);
container.Register(
Component.For<NotificationConfigurationSection>()
.UsingFactoryMethod(
kernel =>
kernel.Resolve<IConfigurationManager>()
.GetSection<NotificationConfigurationSection>("notificationSettings")));
}
}
然后我的测试看起来像
public class WhenInstallingEmailComponents : SpecificationBase
{
private IWindsorContainer _sut;
protected override void Given()
{
_sut = new WindsorContainer();
}
protected override void When()
{
_sut.Install(new EmailInstaller());
}
[Then]
public void ShouldConfigureEmailSender()
{
var handler = _sut
.GetHandlersFor(typeof(ISendEmail))
.Single(imp => imp.ComponentModel.Implementation == typeof(EmailSender));
Assert.That(handler, Is.Not.Null);
}
[Then]
public void ShouldConfigureEmailGenerator()
{
var handler = _sut
.GetHandlersFor(typeof(IGenerateEmailMessage))
.Single(imp => imp.ComponentModel.Implementation == typeof(EmailMessageGenerator));
Assert.That(handler, Is.Not.Null);
}
}
}
这里是 GetHandlersFor 扩展方法
public static class WindsorTestingExtensions
{
public static IHandler[] GetAllHandlers(this IWindsorContainer container)
{
return container.GetHandlersFor(typeof(object));
}
public static IHandler[] GetHandlersFor(this IWindsorContainer container, Type type)
{
return container.Kernel.GetAssignableHandlers(type);
}
public static Type[] GetImplementationTypesFor(this IWindsorContainer container, Type type)
{
return container.GetHandlersFor(type)
.Select(h => h.ComponentModel.Implementation)
.OrderBy(t => t.Name)
.ToArray();
}
}
我使用基础 class SpecficationBase 让我的单元测试读起来像 BDD 风格的测试,但你应该能够理解发生了什么。
- 实例化你的容器
- 调用安装程序来注册您的组件。
- 检查容器中的接口实现类型。
这是 Castle 项目中有关如何测试您的注册码的好文章 link。