什么定义了“隔离”测试?

时间:2019-06-15 18:43:18

标签: c# unit-testing

我有一个名为Customer的类,并且希望对该类及其公共接口进行单元测试。为了能够进行单元测试,我必须独立于其{em> real 依赖项来测试Customer。除了Customer外,我还有一个Monster类,已经创建。

我的应用程序使用的游戏框架定义了Shape(代表形状)和Vec2F(代表用于数学的向量)。 Customer依赖(使用)ShapeVec2F。它还使用Monster

现在,我必须模拟这些真实的依赖关系,以使我的测试成为单元测试而不是集成测试。但是,定义“真实”依赖关系的是什么?就像我会理解为什么我要嘲笑自己的Monster实现,但是从我使用的框架来看Vec2FShape似乎是这样的基本结构。

3 个答案:

答案 0 :(得分:0)

测试应与其他测试隔离。为此,您需要模拟被测系统消耗的所有全局状态。

如果受测系统未使用全局/共享状态-则不进行模拟。
在理想的情况下,建立新数据库需要花费毫秒的时间,您可以为每个测试创建新数据库(EF Core中的内存数据库)。

但是在我们的现实世界中,我们具有表示全局状态的依赖项,否则,它仍然会使测试变慢(Web服务,文件系统,任何外部资源)。

您想模拟这些依赖关系以提供更快的反馈(单元测试)。

您可能具有非常复杂的依赖项层次结构,它们不使用全局状态或外部资源,但是使用这些依赖项配置测试用例将变得非常复杂和困难。 在这种情况下,您将围绕非常非常复杂的依赖项引入一个抽象并将在用户的测试中对其进行模拟。

在您的特定测试用例中,除非框架类依赖于绘图屏幕逻辑(取决于环境API),否则我什么都不做。

答案 1 :(得分:0)

由于测试软件是一项艰巨的任务,因此您将其划分为多个任务以使其易于管理。在单元测试中,您的重点是查找可以通过单独查看小型软件来发现的错误。也就是说,单元测试旨在发现一种特殊的错误。例如,集成测试针对的是另一种错误,这些错误无法通过单元测试找到。

专注于在孤立的软件中查找错误并不是不是,这意味着您真的必须通过模拟依赖项从技术上隔离该软件。如今,模拟框架使模拟变得相当容易(尽管编程语言的难度不同)。尽管如此,嘲笑总是要付出额外的努力,并且也有缺点。例如,使用模拟的测试与代码的实现更加紧密地联系在一起,因此,如果实现的细节发生变化,则更有可能需要维护。

因此,仅在有充分的理由进行模拟时才应进行模拟。充分的理由是:

  • 您不能轻易地使组件依赖(DOC)的行为符合测试的预期。
  • 调用DOC是否会引起任何非专业行为(日期/时间,随机性,网络连接)?
  • 测试设置过于复杂和/或需要大量维护(例如需要外部文件)
  • 原始DOC为您的测试代码带来了可移植性问题。
  • 使用原始DOC是否会导致构建/执行时间过长?
  • 是否存在使测试不可靠的DOC稳定性(成熟度)问题,或者更糟糕的是,甚至还没有DOC?

例如,您(通常)不模拟诸如sincos之类的标准库数学函数,因为它们没有上述任何问题。在您的情况下,对于Vec2FShape也是一样,但是您必须自己判断。上面列出的条件应该可以为您提供帮助。

答案 2 :(得分:0)

听起来 Customer 是域级类型。在这种情况下,您应该将依赖关系倒置为 ShapeVec2F(这看起来像视图层实现),因为框架是一个细节,它比 {{1} } 是。