使用依赖性Inj的依赖性破坏技术用于单元测试

时间:2010-03-09 19:10:55

标签: unit-testing testing dependency-injection

目前正在阅读Roy Osherove撰写的“单元测试艺术”。我差不多走了一半,到目前为止,它是一本很棒的书。我将要求所有人将IOC个容器从此讨论中删除。他只是简单地提到了他们(实际上说IOC超出了我不理解的书的范围,并且是我可以批评这本书的少数几个地方之一)。无论如何,除了国际奥委会之外,各种技术都是:

  1. 构造函数注入
  2. 物业注入
  3. 软件工厂和静力学
  4. 软件工厂和虚拟方法
  5. 方法注入
  6. 列表项
  7. 好的,我将描述我对上述每种方法的不满意  1. 构造函数注入 - 初始化对象会让人感到困惑和困难,尤其是在必须传递大量依赖项的情况下。  2. 房产注入 - 罗伊似乎喜欢这种技术,但这是我最不喜欢的。如果您有一堆依赖项,那么用户必须记住初始化该类所需的每个依赖项。我会说这是容易出错和杂乱的。对于不熟悉它的人来说,很难对班级进行初始化  3. 软件工厂和静力学 - 虽然我认为不喜欢技术,但我不喜欢依赖国家。我喜欢处理完全无状态的物体,但到目前为止我认为它是最好的技术  4. 软件工厂和虚拟方法 - 与上述技术类似,但允许您从类继承并仅覆盖设置依赖关系并将其更改为存根的函数。我的想法类似于3 - 它只是让那个试图找出单元测试失败原因的人有点混乱。
     5. 方法注入 - 我所能说的只是ewwwwwww ...传递你所调用的每个方法的每个依赖关系。够了。

    我想到了另一种方式,我更喜欢上面列出的每种方法。我一般不鼓励条件编译,但我认为在一些你轻易使用它的地方它是有道理的。我建议标准化一个名称,以便为您的测试设置依赖关系。例如:

    .InitalizeDepForTesting(IFileSystem file, IDatabase data, IEventLog event, ...)
    

    然后将上述语句包装在条件编译语句中:

    #If DEBUG
          public void InitializeDepForTesting(...)
    #endIf
    

    因此,您的内部依赖关系将继​​续按原样运行,并且不需要进行更改。你还可以防止破坏构造函数并将所有依赖项与一堆其他“东西”一起传递。就生产代码而言,没有任何变化,一眼就能看出如何初始化测试对象。你们都觉得怎么样?

4 个答案:

答案 0 :(得分:4)

构造注入是更清晰的选择,因为它清楚地建立了您的依赖关系。如果它们太多而且令人困惑,则可能表明您的设计存在问题。

答案 1 :(得分:4)

基于构造函数的注入似乎是社区中的明显赢家(并且是我使用的唯一方法)。

你要求IoC从讨论中删除,但这就像要求我们讨论用记事本编写.Net代码。当然可以做到,但你为什么要这样做?正确使用IoC容器通常允许您在运行时通过一次调用构建整个应用程序。从那时起,您可以使用正确的依赖项正确设置所有实例。而且甚至没有提到用于单元测试的自动模拟所做的所有工作。

正如其他人所指出的那样,如果你有很多依赖项,你的构造函数会让你感到困惑,那么你真的需要重新考虑你的设计。在你读完罗伊的优秀书后,我建议你拿一份鲍勃叔叔的“清洁代码”。

答案 2 :(得分:2)

a。)我和PicoContainer的人群在一起:ConstructorInjection是要走的路。清晰的语义和明确的执行。

b。)关于您的测试方法:我更喜欢使用Mocks,然后依靠IOC进行对象组装。

答案 3 :(得分:0)

  

我要请大家离开国际奥委会   这个讨论中的容器。

通过这样做你会产生问题。 我理解你的理由但是,如果你考虑一个合适的IOC,所有你的异议都没有实际意义。