【发布时间】:2010-09-28 15:04:22
【问题描述】:
我很好奇人们发现了哪些策略来对不涉及为每个测试方法加载(并且可能是卸载)真实数据库的数据访问类进行单元测试?您是否使用模拟对象来表示数据库连接?如果是这样,您是否需要将模拟对象传递给每个被测方法,从而强制 API 需要一个真正的数据库连接作为每个方法的参数?或者,您是在 setup() 中将模拟对象传递给构造函数吗?
我有一个类正在实现我认为是数据映射器(或者可能是网关)模式。它是负责封装 SQL 并返回(或保存)“业务对象”的类。其余代码可以与这个映射层和业务对象交互,完全不考虑持久性模型。此代码需要拥有/维护或只知道真实系统中的实时数据库连接。在测试中模拟这个是很棘手的。
问题是如何对这些映射器类之一进行单元测试。我最常看到的在 xUnit 下创建单元测试的做法是使用测试的 setup() 方法来实例化 SUT(被测系统),通常是您正在测试的对象,并将其存储在本地测试类中的变量。然后,您的每个测试方法都与该 SUT 的唯一实例进行交互。
但假设是,您在 setup() 方法中所做的任何事情都可能会复制到您的真实代码中的某个位置。因此,您必须将设置过程视为“每次我需要在现实世界中使用此对象时,我都希望重复重现此内容”。如果我在设置中将一个数据库连接传递给映射器的构造函数,那很好,但这是否意味着每次我想真正使用一个时,我都必须将一个实时数据库连接传递给映射器对象的构造函数?想象一下,您将有各种各样的地方需要检索或存储业务对象,并且要使用数据映射器对象,您每次都需要传入 db 连接?
就我而言,我正在尝试为这些数据映射器对象建立测试,以实现以下目标:
- 不需要实例化数据库连接对象并将其传递给映射器类的每个方法。
- 不要求测试用例连接到真实数据库或为每个测试方法动态创建真实但“测试”的数据库。
我基本上看到了两个建议,将连接对象作为参数传递(我已经解决过)或扩展 SUT 类仅用于测试并覆盖您在现实世界中使用的任何数据库连接设置过程以使用模拟代替系统。
我很好奇是否有其他人使用任何语言面临这些问题,以及您为解决这些问题做了什么?也许我缺少一些明显的东西?
【问题讨论】:
标签: unit-testing testing tdd mocking