代码之家  ›  专栏  ›  技术社区  ›  pete the pagan-gerbil

在TDD中使用“真实”实用程序类而不是模拟是否可以接受?

  •  10
  • pete the pagan-gerbil  · 技术社区  · 15 年前

    我有一个项目,我试图学习单元测试和TDD实践。我发现我正陷入一个相当混乱的情况,我花了很长时间为一个实用程序类建立模型,这个类几乎无处不在。

    从我所读到的关于单元测试的内容来看,如果我在测试MyClass,我应该模拟任何其他功能(比如UtilityClass提供的功能)。只使用UtilityClass而不是为所有不同的测试用例设置mock可以接受吗(假设UtilityClass本身有一组全面的测试)?

    编辑:我正在做很多准备工作。 我正在为地图建模,在不同的位置有不同的对象。我的实用程序类上的一个常用方法是GetDistanceBetween。我正在测试的方法对事物的影响取决于它们各自的属性,因此,例如,一个选择一个点的5个单位内的所有对象并且年龄超过3岁的测试将需要几个测试(获取范围内的旧对象、忽略范围外的旧对象、忽略范围内的年轻对象、正确地处理每个情况的倍数)和所有这些测试都需要设置“GetDistanceBetween”方法。将其乘以每个使用GetDistanceBetween的方法(几乎每个方法)和该方法在不同情况下应返回的不同结果,这将是一个很大的设置。

    我可以看到,随着我进一步开发,可能会有更多的实用程序类调用,大量的对象和这些模拟实用程序类上的许多设置。

    5 回复  |  直到 15 年前
        1
  •  23
  •   Aaron Digulla    15 年前

    规则不是“模拟一切”,而是“使测试简单化”。如果

    1. 您无法通过合理的努力创建实例(读:您需要一个方法调用,但要创建实例,您需要一个工作数据库、一个数据库连接和五个其他类)。
    2. 附加类返回不稳定的值(如当前时间或数据库中的主键)
        2
  •  9
  •   Lunivore    15 年前

    TDD并不是真正的测试。它的主要好处是帮助您设计干净、易于使用的代码,其他人可以理解和更改这些代码。如果它的主要好处是测试,那么您将能够在代码之后而不是之前编写测试,并具有相同的效果。

    如果可以的话,我建议你不要把它们当作“单元测试”。相反,将您的测试视为如何使用代码的示例,以及对代码行为的描述,这些描述说明了代码为什么有价值。

    如果您的实用程序类是类行为的核心部分,并且您的类没有价值,或者没有它们它的行为就没有意义,那么不要嘲笑它们。

    1. 协作类的行为是复杂的,独立于您感兴趣的类的行为。

    2. 创建协作类不是类的一个有价值的方面,也不需要成为类的职责的一部分。

    希望这有意义!如果你喜欢,可以看看BDD,它使用的词汇远远多于“test”。

        3
  •  4
  •   Carl Manaster    15 年前

    理论上你应该试着嘲笑所有的依赖关系,但实际上这是不可能的。E、 你不会去模仿标准库中的基本类。在您的例子中,如果实用程序类只包含一些基本的helper方法,我想我就不会去嘲笑它了。

    如果它比这更复杂,或者连接到一些外部资源,则必须模拟它。您可以考虑创建一个专用的mock builder类,它将为您创建一个标准mock(定义了一些标准存根等),这样您就可以避免在所有测试类中模拟代码重复。

        4
  •  2
  •   Darin Dimitrov    15 年前

    不,这是不可接受的,因为您不再孤立地测试类,这是单元测试最重要的方面之一。即使该实用程序有自己的一组测试,也可以使用它对该实用程序的依赖性对其进行测试。为了简化模拟对象的创建,可以使用模拟框架。以下是一些流行的选择:

    当然,如果这个实用程序类是私有的,并且只能在被测类的范围内使用,那么就不需要模拟它。

        5
  •  1
  •   philant    15 年前

    是的,可以接受。重要的是让UtilityClass进行彻底的单元测试,并且能够区分测试是因为被测类还是因为UtilityClass而失败。


    必须创造 太多了 测试设置中的对象表示环境变得太大,因此没有得到足够的控制。现在是恢复模拟对象的时候了。

    推荐文章