模拟 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 风格的测试,但你应该能够理解发生了什么。

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

这是 Castle 项目中有关如何测试您的注册码的好文章 link