2008-12-06 76 views
4

我一直听说,通过单元测试,我们可以捕获代码中的大部分错误,我真的相信这是真的。但我的问题是在大型项目中,每个类都依赖于许多其他类,你如何去测试这个类的单元测试?由于复杂性和编写存根所需的时间,将其他类别划分出来没有多大意义。你对此有何看法?你如何测试一个依赖于许多其他类的类?

回答

11

部分原因是,它迫使你以减少依赖,从而产生可测试的代码。通过最小化依赖关系,您将提高代码的可维护性和可重用性,这两个特性都是非常理想的。

由于您将引入测试到现有的代码库,你无疑会遇到很多难以测试的情况下,这将需要重构正确测试。这种重构将增加代码的可测试性,同时减少依赖关系。

之所以它很难与测试,以改造代码就是为什么许多主张以下测试驱动开发。如果您先编写测试,然后编写代码以通过测试,那么您的代码默认情况下会更易于测试和解耦。

0

我不加快速度对整个单元测试的事情,但我认为,各单位应该代表某种考验。测试用例应该测试一些程序。程序不一定限于一个班级。

举例来说,如果应用程序可以被分解为原子成分,则一个测试案例可能存在为每个组件和组件之间的过渡中的每个适用链。

4

使用模拟框架为您存档类。嘲讽框架(我使用Rhino Mocks for C#/ .NET)可以很容易地去除依赖关系。与依赖注入一起使用时,您的类可以轻松地从其他类中分离出来,并且不需要太多工作就可以实现它们。请注意,有时它变得更容易“伪造”某些东西而不是模拟。我最终伪造了一些类,但通常这些类很容易编写 - 它们只包含“好”或“坏”数据并将其返回。没有涉及逻辑。

0

在我们的项目中,开发人员有责任从一开始就编写和维护存根。

即使存根花费的时间和金钱,单元测试提供了一些不容忽视的优点(你同意它太)。它可以实现测试过程的自动化,减少发现包含在更复杂应用程序中的错误的困难,并且测试覆盖率通常得到增强,因为每个单元都受到了重视。

凭我的经验我已经看到,在我们已经把单元测试以低优先级项目都在后一阶段,其中单个改变或者破坏东西,或者需要额外的测试受到影响。

单元测试增加了我作为软件开发人员的信心。使用测试,优势

0

我更喜欢单元测试功能,它可能对应或不对应于单个类。这种粒度的单元测试在我看来是在测试所需的工作,对客户的反馈(因为功能是他们所支付的)以及单元测试的长期效用(体现需求,说明如何对案件)

因此,嘲讽很少需要,但一些测试跨越多个类别

0

但我的问题是,在大型项目 其中每个等级取决于许多 其他类你如何去测试课程单元 ?

首先,你明白“每个班级都依赖于很多其他班级”是一件坏事,对吗?而且这不是一个大项目的功能,而是一个糟糕的设计? (这是TDD的好处之一,它往往会阻碍这种高度耦合的代码。)

打桩每其他类不 做,因为这两个 的复杂性和需要 的时间太多意义写存根。

更何况它不能帮助设计问题。更糟的是,对所有存根的投资实际上可能是重构的障碍,如果只是心理上的障碍。

更好的方法(恕我直言)是从内部开始在类上,随时更改设计。通常我会通过做所谓的“内部依赖注入”来解决这个问题。这涉及使方法签名保持不变,但从相关性中提取所需的数据,然后提取保存实际逻辑的函数。一个简单的例子可能是:

public int foo(A a, B b) { 
    C c = a.getC(); 
    D d = b.getD(); 

    Bar bar = calculateBar(c, d); 

    return calculateFoo(bar, this.baz); 
} 

Bar calculateBar(C c, D d) { 
    ... 
} 

int calculateFoo(Bar bar, Baz baz) { 
    ... 
} 

现在我可以写calculateBar和calculateBaz测试,但我并不需要设立内部状态(this.baz)担心,我也不需要担心关于创建A和B的模拟版本。

在使用现有接口创建这样的测试之后,我寻找机会将更改推送到接口,例如更改Foo方法以采用C和D而不是A和B.

任何有意义的东西?

0

你说得对,所有你正在测试的类所依赖的类都是不值得的。如果你改变界面,你也必须保持你的模拟。

如果您正在测试的人使用的类已经过测试,那么跨越几个类就可以进行测试。

它有时简单嘲笑的对象:当

  • 目的是或使用外部资源,例如数据库或网络连接,磁盘
  • 对象是一个GUI
  • 对象不是[尚未]可
  • 对象的行为是不确定的
  • 对象是昂贵的设置
0

我觉得你可能需要重构来降低复杂度。

我发现,它可以是非常有帮助的重构类(即把它们分解),所以每个人都有一个单独的责任(不太复杂)。然后你可以单元测试这个责任。你可以使用模拟框架轻松地模拟和初始化依赖关系。我觉得FakeItEasy是非常好的,易于使用,你可以找到很好的例子

0

下面是一个非常大的企业项目运作良好,为我们的可测试性,但也为稳健的设计原则:

  1. 通过类构造函数来明确你的依赖关系。

  2. 而不是采取具体类的依赖关系,创建一个定义您需要的功能接口,并采取这些接口从类的构造函数,而不是依赖。这也允许您在需要时应用依赖注入模式。

  3. 使用像Moq这样的现有框架之一,因此您不需要编写完整的界面测试实现,但在运行时您可以从单元测试中创建Moq对象。