模拟对象与测试数据库

时间:2010-06-24 15:56:39

标签: unit-testing mocking

与具有已知数据的静态测试数据库相比,使用模拟对象的优势是什么,并且在对数据库进行测试时使用事务确保没有任何更改。

6 个答案:

答案 0 :(得分:14)

你可以做到这两点。使用模拟对象测试BLL逻辑,然后使用测试数据库测试DAL逻辑。这样,如果出现问题,你可以很容易地看出问题出在哪里,哪个测试失败了。

答案 1 :(得分:6)

首先,使用模拟将比连接到外部数据库快得多。然而,主要原因是每次运行测试时模拟行为都是相同的,您无法保证像数据库这样的外部服务,这意味着单元测试不会随机失败。您还可以使用模拟对象轻松模拟要处理的任何类型的故障。

对于真实数据库运行集成测试也是一个好主意,但要测试配置和性能等。

答案 2 :(得分:2)

如果可以确保静态测试db在测试期间没有改变,那么我认为静态测试db优于mock对象。但是,这取决于您要测试的内容以及要测试的代码的复杂性。我会使用模拟对象,因为与db相比,它们更易于维护。

答案 3 :(得分:1)

通常你会使用这两种方法。

对于单元测试,您将使用模拟对象。这样,您可以以更细粒度的方式测试系统,因为您可以模拟每个对象 - 不仅是包装数据库连接的对象。通常,在分离所有依赖项时对每个类进行单元测试是一种好习惯。好处是 - 它可以测试所有级别的所有错误处理,并确保测试所有代码路径,当您遇到测试失败时,您可以立即找到原因等。

对于集成和端到端测试,您可以测试系统的大部分或整个系统。然后你将连接到数据库(因为这个连接是测试的一部分)。显然,您必须确保数据库处于已知状态等,等等。

您最终将获得比集成测试更多的单元测试,因此实现它们非常快速非常重要 - 这是使用模拟对象的另一个优势。

答案 4 :(得分:1)

想象一下,你即将编写一个不存在的类。也许这是一个控制器。这不是直接与数据库对话的东西。

你很清楚它应该如何表现,你知道它应该负责什么,以及它应该委托给其他服务(使用单一责任原则)。所以你编写接口来表示它将要使用的辅助类的角色。

然后,您将编写一个示例,说明如何使用您即将创建的类。如果您愿意,可以将示例称为单元测试。你模拟了与助手类的交互。当您运行该示例时,它会失败,因为您还没有编写代码。您现在可以使用辅助类的接口编写代码以使其通过 - 您还没有编写它们。

然后你对助手类做同样的事情,嘲笑他们的助手。

最终你会到达一个与数据库对话的课程。或者它可能会与Web服务进行对话。或者数据可能是静态的,也可能是内存中的数据。 (这对原始课程无关紧要,因为你的班级与此分离了。)

此时你还需要一个例子来描述这个类的行为,如果它是一个数据库连接器,你需要一个数据库作为例子。

以这种方式编写代码会产生易于使用和理解的代码,而堆栈中的某些东西不需要额外的代码。这通常比更容易编写的代码更强大。这就是我们有时使用模拟的原因 - 因为首先使用模拟编写测试有助于产生良好,可维护,分离的设计。

答案 5 :(得分:1)

使用db进行测试的设置可能很艰巨。如果您发现自己花费更多时间来设置数据库,只是为了测试业务逻辑的某些功能方面,那么您可能想要使用模拟/伪造。