8

我试图找到答案,但似乎并没有直接讨论很多。我有一个应用程序的组合根,在其中创建一个 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();
        }
    }
4

1 回答 1

8

测试组合根是否有意义?

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

然而,这些测试专门针对系统接线的正确性。您不想测试单个类是否正确运行,因为某些单元测试已经涵盖了这一点。您也不想测试类是否以正确的顺序调用其他类,因为这是您想要在正常集成测试中测试的内容(调用 MVC 控制器并查看调用是否最终进入数据库是此类集成测试的一个示例)。

以下是您可能应该测试的一些内容:

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

然而,为了能够做到这一点,您需要有一个可验证的 DI 配置

请注意,并非所有人都同意这种观点。然而,我的经验是,验证配置的正确性非常有价值。

因此,使用某些 IoC 容器测试这些东西可能具有挑战性,而其他 IoC 容器具有可以帮助您解决此问题的工具(但遗憾的是,Unity 缺少大多数这些功能)。

一些容器甚至有某种可以调用的验证方法来验证配置。每个库的“验证”含义都不同。例如,Simple Injector(我是 Simple Injector 的主要开发人员)有一个Verify方法可以简单地迭代所有注册并调用GetInstance它们中的每一个以确保可以创建每个实例。我总是建议您Verify尽可能在他们的组合根中调用用户。例如,这并不总是可行的,因为当配置变大时,对验证的调用可能会导致应用程序启动太慢。但是,这是一个很好的起点,可以消除很多痛苦。如果需要很长时间,您始终可以将调用移至自动化测试。

而对于 Simple Injector,这仅仅是个开始。Simple Injector 包含诊断服务,用于检查容器的常见错误配置,例如前面提到的“生活方式不匹配”​​。

因此,您绝对应该进行测试,但我不确定是否将这些测试称为“单元测试”,尽管我设法单独运行这些测试(无需访问数据库或 Web 服务)。

于 2013-08-28T20:10:31.117 回答