【发布时间】:2012-01-26 03:53:37
【问题描述】:
我刚开始进行单元测试,想知道如何对正在对我的数据库进行实际更改的方法进行单元测试。最好的方法是将它们放入事务然后回滚,还是有更好的方法?
【问题讨论】:
标签: c# sql unit-testing
我刚开始进行单元测试,想知道如何对正在对我的数据库进行实际更改的方法进行单元测试。最好的方法是将它们放入事务然后回滚,还是有更好的方法?
【问题讨论】:
标签: c# sql unit-testing
如果您想要正确的测试覆盖率,您需要两种类型的测试:
单元测试,模拟您所有的实际数据访问。这些测试不会真正写入数据库,而是测试所做的类的行为(它在其他依赖项上调用哪些方法等)
系统测试(或集成测试)检查您的数据库是否可以被访问和修改。我会在这里考虑两种类型的测试:针对每个模型对象的简单普通 CRUD 测试(创建/读取/更新/删除),针对您的实际方法的更复杂的系统测试,以及您认为有趣或有价值的所有测试。这里的好的做法是让每个测试从一个空的(或“准备好测试”)数据库开始,做它的工作,然后检查数据库的状态。事务/回滚是实现这一目标的一种好方法。
【讨论】:
对于单元测试,您需要模拟或存根数据访问代码,大多数情况下您都有存储库接口,您可以通过创建将数据存储在内存中的具体存储库来存根它,或者您可以使用动态模拟框架对其进行模拟..
对于系统或集成测试,您需要在每次测试方法之前重新创建整个数据库,以便在每次测试之前保持稳定状态。
【讨论】:
根据前面的一些答案,如果您想测试数据访问代码,那么您可能需要考虑模拟和系统/集成测试策略。
但是,如果您想对您的 SQL 对象(例如存储过程、视图、表中的约束等)进行单元测试,那么有许多可能感兴趣的数据库单元测试框架(包括我编写的一个) )。
有些在 SQL 中实现测试,有些在您的代码中实现测试并使用 mbUnit/NUnit 等。
我已经写了很多文章,其中包含有关我如何处理此问题的示例 - 请参阅 http://dbtestunit.wordpress.com/
其他可能有用的资源:
【讨论】:
一般的方法是有一种方法来模拟您的数据库操作。这样您的单元测试不依赖于数据库可用或处于某种状态。也就是说,它还意味着有助于模拟数据层所需的隔离的设计。单元测试以及如何做好它是一个巨大的话题。看看 googley 上的 Mock Frameworks 和依赖注入。
【讨论】:
如果您不开发 O/R 映射器,则无需测试数据库代码。您不想测试 ADO.NET 方法,对吗?相反,您想验证是否使用正确的值调用了 ADO.NET 方法。
在 Google 上搜索存储库模式。您将使用 CRUD 方法创建 IRepository 接口的实现并对其进行测试/模拟。
【讨论】:
如果您想针对真实数据库进行测试,这将更像是集成而不是单元测试。将您的测试包装在事务中可能是一个让您的数据库保持一致状态的想法。 我们在基类中完成了这项工作,并使用了 TestInitialize 和 TestCleanup 函数来确保这种情况总是发生。
但是针对真实数据库进行测试肯定会给您带来性能问题。因此,请确保从一开始就可以将数据库访问代码与内存中运行的代码交换。我现在不知道您的目标是哪个数据库访问代码,但像 UnitOfWork 和 Repository 这样的设计模式可以帮助您隔离数据库代码并将其替换为内存解决方案。
【讨论】: