本文介绍了在Castle Windsor 3中,在单元测试中覆盖现有的组件注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试在自动化测试中使用Castle Windsor,例如:

I am attempting to use Castle Windsor in my automated tests like so:

在每次测试中:


  • Setup()函数创建一个Windsor容器,注册每个组件的默认实现

  • Test 函数通过方法 IWindsorContainer.Resolve< T> 访问组件,并测试其行为

  • TearDown()函数处理温莎容器(以及任何已创建的组件)

  • The Setup() function creates a Windsor container, registering default implementations of each component
  • The Test function access the components via the method IWindsorContainer.Resolve<T>, and tests their behavior
  • The TearDown() function disposes of the Windsor container (and any created components)

例如,我可能有15个测试可以访问组件,这些测试间接地导致创建 IMediaPlayerProxyFactory 组件。 SetUp 函数注册了一个足够好的实现 IMediaPlayerProxyFactory ,所以我没有在此注册的维护负担。 15个测试中的每一个。

For example, I might have 15 tests which accesses components which indirectly results in the creation of an IMediaPlayerProxyFactory component. The SetUp function registers a good-enough implementation IMediaPlayerProxyFactory, so I don't have the maintenance burden of registering this in each of the 15 tests.

但是,我现在正在编写一个测试 Test_MediaPlayerProxyFactoryThrowsException ,确认我的系统能够优雅地处理 IMediaPlayerProxyFactory 组件出现错误。在测试方法中,我创建了特殊的模拟实现,现在我想将其注入到框架中:

However, I'm now writing a test Test_MediaPlayerProxyFactoryThrowsException, confirming my system elegantly handles an error from the IMediaPlayerProxyFactory component. In the test method I've created my special mock implementation, and now I want to inject it into the framework:

this.WindsorContainer.Register(
                                 Component.For<IMediaPlayerProxyFactory>()
                                          .Instance(mockMediaPlayerProxyFactory)
                              );

但是温莎抛出了 Castle.MicroKernel.ComponentRegistrationException ,并显示消息已经有一个具有该名称的组件。

But Windsor throws a Castle.MicroKernel.ComponentRegistrationException, with the message "There is already a component with that name."

有什么方法可以使我的 mockMediaPlayerProxyFactory IMediaPlayerProxyFactory 的默认实例,丢弃已注册的组件吗?

Is there any way that I can make my mockMediaPlayerProxyFactory be the default instance for the IMediaPlayerProxyFactory, discarding the component that's already registered?



根据,温莎城堡3允许注册覆盖,但我只能找到一个示例:


According to the documentation, Castle Windsor 3 allows for registration overrides, but I could only find one example:

Container.Register(
    Classes.FromThisAssembly()
        .BasedOn<IEmptyService>()
        .WithService.Base()
        .ConfigureFor<EmptyServiceA>(c => c.IsDefault()));

ConfigureFor BasedOnDescriptor 类。就我而言,我没有使用 FromDescriptor BasedOnDescriptor

ConfigureFor is a method of the BasedOnDescriptor class. In my case I'm not using the FromDescriptor or BasedOnDescriptor.

推荐答案

创建覆盖实例必须做两件事:

There are two things that you have to do to create an overriding instance:


  1. 为其分配一个唯一名称

  2. 调用 IsDefault 方法

  1. Assign it a unique name
  2. Call the IsDefault method

因此,使示例生效:

this.WindsorContainer.Register(
                             Component.For<IMediaPlayerProxyFactory>()
                                      .Instance(mockMediaPlayerProxyFactory)
                                      .IsDefault()
                                      .Named("OverridingFactory")
                          );

由于我计划在许多测试中使用此主要模板,因此我创建了自己的扩展方法:

Because I plan to use this overriding patten in many tests, I've created my own extension method:

public static class TestWindsorExtensions
{
    public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class
    {
        return componentRegistration
                            .Named(Guid.NewGuid().ToString())
                            .IsDefault();
    }
}

现在,示例可以简化为:

Now the example can be simplified to:

this.WindsorContainer.Register(
                             Component.For<IMediaPlayerProxyFactory>()
                                      .Instance(mockMediaPlayerProxyFactory)
                                      .OverridesExistingRegistration()
                          );



稍后编辑

版本3.1引入了 IsFallback 方法。如果我使用 IsFallback 注册所有初始组件,则任何新注册都会自动覆盖这些初始注册。如果当时该功能可用,我会走那条路。

Version 3.1 introduces the IsFallback method. If I register all my initial components with IsFallback, then any new registrations will automatically override these initial registrations. I would have gone down that path if the functionality was available at the time.

这篇关于在Castle Windsor 3中,在单元测试中覆盖现有的组件注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 20:36