2013-08-28 93 views
7

我试图找到答案,但似乎没有直接讨论很多。我有我的应用程序的组成根,我创建一个DI容器并在那里注册所有内容,然后解析需要的所有依赖关系的顶级类。由于这一切都发生在内部 - 单元测试组合根很难。你可以做虚拟方法,受保护的领域等等,但我并不是很喜欢引入这样的东西来进行单元测试。其他类没有大问题,因为它们都使用构造函数注入。所以问题是 - 测试组合根目录是否合理?它确实有一些额外的逻辑,但并不多,在大多数情况下,在应用程序启动期间会出现任何故障。 一些代码,我有:组合根是否需要单元测试?

public void Initialize(/*Some configuration parameters here*/) 
    { 
     m_Container = new UnityContainer(); 

     /*Regestering dependencies*/ 

     m_Distributor = m_Container.Resolve<ISimpleFeedMessageDistributor>(); 
    } 

    public void Start() 
    { 
     if (m_Distributor == null) 
     { 
      throw new ApplicationException("Initialize should be called before start"); 
     } 

     m_Distributor.Start(); 
    } 

    public void Close() 
    { 
     if (m_Distributor != null) 
     { 
      m_Distributor.Close(); 
     } 
    } 
+0

你想在这里测试什么?组合根是应用程序平台的钩子。你不会找到一个简单的方法来模拟所有的基础架构代码。 –

+0

那么,例如,想要测试进入的配置是否正确解析,开始调用m_Distributor.Start()等等。所以我不确定这是否需要太多... –

+0

您是否使用XML文件进行配置?你能否将所有容器配置移动到安装程序(安装程序位于Castle Windsor,它们在Ninject中称为模块)类?我从来没有用过Unity。 –

回答

8

它多大意义,在所有测试的组成根源在哪里?

你想知道你的应用程序是否正确写入?你可能会这样做,这就是你编写测试的原因。出于同样的原因,你应该测试你的组合根。

但是这些测试在系统的布线的正确性被特异性靶向。你不想测试一个类是否正常工作,因为这已经被一些单元测试覆盖了。无论你想测试类是否调用正确的顺序其他类,因为这是你想要在你的正常的集成测试,以测试(调用一个MVC控制器,看看通话是否在数据库最终是什么这样的集成测试的例子)。

这里有一些事情你应该测试:

  • 这一切顶级类可以解决。这样可以防止您必须点击应用程序中的所有屏幕才能确定是否所有连线都正确。
  • 的组件只依赖于同样或更长时间生活服务。当组件依赖于配置了较短生命周期的另一个组件时,该组件将“提升”该依赖的生命周期,这往往会导致难以复制和修复的错误。检查这类问题很重要。这种类型的错误也被称为生活方式不匹配或俘虏依赖。
  • 这是至关重要的应用程序的正确性装饰和其他拦截机制,正确应用。装饰可以为实例增加横切关注点,如事务处理,安全性和缓存,并且这些问题都以正确的顺序执行(例如安全检查必须查询缓存之前进行)是非常重要的,但它可能很难使用正常的集成测试来测试它。

但是要做到这一点,您需要有verifiable DI configuration

难道虽然注意到not everybody股这一观点。然而,我的经验是验证你的配置的正确性是非常有价值的。

所以测试这些东西都可以用一些IoC容器具有挑战性,而其他IoC容器有设施,以帮助您完成此(但不幸的是团结的缺乏这些功能最)。

一些容器,甚至有某种验证方法,可以被称为是将验证配置的。每个图书馆的“验证”意味着不同。简单的注射器(我是简单注射器的主要开发者)有一个Verify方法,它将简单地迭代所有注册,并在每个注册中调用GetInstance以确保可以创建每个实例。我总是建议用户尽可能在他们的作品根目录中拨打Verify。这并不总是可能的,因为当配置变大时,对验证的调用可能导致应用程序启动太慢。但是,这仍然是一个很好的起点,可以消除很多痛苦。如果需要很长时间,您可以随时将呼叫转移到自动化测试。

对于简单的喷油器,这只是一个开始。简单注射器包含Diagnostic Services,用于检查容器上常见的错误配置,例如前面提到的“生活方式不匹配”​​。所以你绝对要测试,但我不确定是否要调用这些测试“单元测试”,尽管我设法孤立地运行这些测试(无需击中数据库或Web服务)。

+0

很高兴看到有人分享这个意见。我发现在过去一年左右,自从我开始在我的.NET项目中练习TDD以来,绝大多数仍然存在的错误都出现在我的IoC设置中,因为我没有或无法很好地测试它们。 – TeaDrivenDev

+0

我不会为不公开配置或具有验证方法的容器测试CompositionRoot。因为在应用程序的任何位置注入新的服务非常容易,而且容易忘记测试。因此,任何手动检查都会给人一种虚假的安全感。然后再次,我不会使用不能确保所有东西连线正确的容器。 – jgauffin

+1

@jgauffin:我认为任何容器都不能给你绝对的安全。但是,我确实同意某些容器可以更容易地做坏事。稍后在服务器上注册服务实际上是一件坏事,这就是Autofac,Simple Injector和Griffin.Container不支持的原因。 – Steven