模拟WindsorContainer以测试ComponentRegistration

时间:2018-12-18 13:13:52

标签: c# moq castle-windsor

我正在使用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); 

但是它们都不起作用。
有人可以帮助吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

答案中的单元测试不会测试任何内容。第一个问题是您要模拟要测试的系统。

测试您的被测系统实现的整个要点。

然后,您唯一的测试是对模拟对象的调用已发生。验证实际注册很容易。

此示例使用安装程序,因为我使用它们来清理许多注册代码。

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();
    }
}

我使用基类SpecficicationBase来使单元测试像BDD样式测试一样读取,但是您应该能够了解发生了什么。

  1. 实例化您的容器
  2. 致电安装程序以注册您的组件。
  3. 检查容器中接口的实现类型。

这是Castle项目的一个不错的link,内容涉及如何测试您的注册码。

答案 1 :(得分:-1)

一个同事帮助了。

它是这样的:

_container.Verify(f => f.Register(It.Is<ComponentRegistration<IMandatorMapper>>(reg => reg.Implementation == typeof(MandatorMapper))), Times.Once);