接口如何使单元测试和模拟更容易?

Gur*_*epS 14 unit-testing mocking

人们常说接口使得模拟和单元测试变得更容易.接口如何帮助解决这个问题?

Jan*_*zny 6

接口的本质是提供许多实现,从而实现模拟.

特别是在集成测试中,您可以提供依赖系统模型的版本(例如,Web服务).您可以提供最简单的接口实现,以提供单元测试正确完成所需结果,而不是实际调用依赖系统甚至模块或复杂且难以实例化的类型.

除此之外,当你在单元测试中使用一个实际的依赖类型(称之为BigGraph)隐藏它背后的复杂对象模型时,你实际上是在进行集成测试而不是单元测试.如果任何依赖类型(BigGraph)中存在错误,而不是您正在测试的类型,那么您的测试很容易中断,因此不会进行单元测试.使用模型降低了发生这种情况的风险.

我已经看到许多持续集成系统显示一个错误的几十个错误,当它们应该显示一个或最多几个时,因为太复杂的对象模型和错误编写的单元测试 - 不使用模型.

今天,模拟框架比过去更复杂(字节码修改等),因此有时并不总是需要接口甚至虚拟方法,但是无神经接口使它们成为可能.

如果您的对象模型过于复杂和混乱(例如,您的接口严重依赖于其他类型/接口),接口将无济于事 ; 然后实施/嘲笑这一切都是一种痛苦.


Aar*_*lla 5

如果你有一个类,你可以有很多依赖项

  • 疯狂的构造函数(许多参数,或者它需要一些其他类需要第三个类,需要第四个类需要有效的数据库连接)

  • 要以任何方式使用该类,必须正确初始化它(例如,您必须将其它一些必须有效的对象传递给它)

  • 班级有州.由于某种原因,该状态可能在测试期间发生变化.

  • 该类可能具有或使用静态字段

在您的许多测试中,这些依赖关系通常是无关紧要的,您宁愿不必处理它们.

使用接口,您可以创建一个简单的mock类,它只实现您需要的几个方法.大多数模拟框架都内置了对此的支持.这里的"实施"通常意味着"返回固定价值".这样,您可以快速构建测试类所需的环境.

因此,例如,如果您的类需要从数据库中读取记录,您可以改为模拟一个ResultSet只返回行的记录.因此,您不必拥有真正的数据库,您不需要创建连接(这很慢并且可能由于多种原因而失败),您不必关心数据库中的数据(所以你不要不必删除/删除表并用测试数据再次填充它们等等.