5

我有一些存储库类,它们是为了与不同类型的数据进行通信,从IRepository接口派生。

在实现中,代码与数据源对话,无论是 XML 文件目录还是数据库,甚至只是缓存。是否可以对这些实现中的任何一个进行可靠的单元测试?我没有看到模拟实现工作,因为那时我只测试模拟代码而不是实际代码。

4

4 回答 4

7

不,当你编写一个使用IRepository. 对于 的实现IRepository您需要针对适当的数据源进行测试。对于数据库来说,这有点痛苦——对于文件系统来说,稍微少一些。

在可能的情况下,如果您可以用流或读取器来表达您的实现,您的生活将会变得更轻松:对实现的这些部分的测试可以针对内存中的数据源,或者来自测试程序集中资源的流。当然,您可能需要一些针对真实数据库或文件系统的测试,但希望更少。

您是否将此类测试称为“单元”测试取决于您如何定义单元测试;就个人而言,我不太关心涉及的名称,但我确实关心进行测试。特别是对于数据库,这些可能会有些痛苦(特别是如果您希望能够并行运行测试) - 但根据我的经验,它们也可能非常有价值。

于 2010-05-02T11:08:16.997 回答
1

我认为,如果您正在测试实际持久化或查询数据的代码,您可能实际上想要访问数据库。

这些是集成测试而不是单元测试。

您可以设置一个测试数据库,在其中您知道数据的状态,并针对它运行测试。您可能还想告诉测试它们与您的单元测试不同,并且不需要在每次签入时都运行(在 nUnit 中,您可以使用告诉它不要运行的属性来装饰您的测试类)

于 2010-05-02T11:08:27.870 回答
1

从广义上讲,您不会对任何唯一目的是与数据源对话的代码进行单元测试。您可能仍希望自动测试存储库,但根据定义,这样的测试将是集成测试。您可能不希望将这些测试作为“第一次通过”构建的一部分来运行,例如设置数据库并在您自己之后进行清理可能会花费大量时间。

如果您的存储库有其他职责(例如实现工作单元模式),那么您可能希望单独对它们进行单元测试。

于 2010-05-02T11:12:21.280 回答
1

在 IRepository 实现的某个时刻,您将使用第三方 API,该 API 将实际读取/写入数据库/文件/xml。您要做的是模拟这些 API,以确保您的代码以正确的顺序调用正确的 API。

因此,如果您正在从数据库中读取数据,您可以模拟 SqlConnection 和 SqlCommand 并确保在这些类上调用正确的方法。如果您正在写入流,则可以模拟流并确保刷新并处置它(例如)。

于 2010-05-02T11:12:42.230 回答