为了账号安全,请及时绑定邮箱和手机立即绑定

模拟 WindsorContainer 以测试 ComponentRegistration

模拟 WindsorContainer 以测试 ComponentRegistration

C#
MYYA 2022-06-18 17:50:45
我正在使用 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);但它们都不起作用。有人可以帮忙吗?提前致谢。
查看完整描述

1 回答

?
喵喵时光机

TA贡献1846条经验 获得超7个赞

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


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


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


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


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


查看完整回答
反对 回复 2022-06-18
  • 1 回答
  • 0 关注
  • 142 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信