0

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

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

提前致谢。

4

1 回答 1

1

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

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

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

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

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 项目中关于如何测试注册码的一个很好的链接。

于 2018-12-21T18:17:14.477 回答