每个人都喜欢单元测试。但是测试实体的持久性有点不同。您正在使用不同的语言测试跨多个层发生的进程。您的测试有副作用(从某种意义上说,正在添加/修改行等)。
我想知道你是怎么做到的。例如,您的测试是否创建了一个全新的数据库模式并且每次都丢弃它?您是否必须维护用于创建测试模式的SQL脚本并使其与生产数据库保持同步?您是否针对您在生产中使用的相同数据库产品进行测试?您是随机生成实体的状态,还是始终使用相同的值?如何配置测试以确保它们是针对测试数据库而不是生产数据库执行的?
在这方面我可能还没有想过一些重要的问题。为了点追踪者的利益,我将标记答案似乎具有最小的副作用并且最容易实现。
答案 0 :(得分:1)
单元测试数据持久性几乎是不可能的,所以我通常在集成级别上进行。
关于数据库,在我当前的项目中,集成测试套件确实丢弃了整个模式,并从头开始重新创建所有内容(这是从构建服务器运行测试时使用的)。但是,您也可以针对已创建的数据库运行测试 - 如果您正在从您的计算机进行测试/调试并且不想浪费时间或丢失测试数据,这是有意义的。您应该维护您的数据库脚本(它们应该与生产的脚本相同) - 这样您就可以测试脚本以及.Net代码。通常,脚本不会创建任何数据(除了静态数据之外) - 它应该是测试的一部分,用于创建测试数据,对其执行某些操作并验证期望 - 这样做可以针对每个数据库运行测试正确的架构。在创建测试数据时,我们通常会使用随机标识符和唯一字段,并对其他所有内容进行硬编码。
关于环境管理,您应该已经有一些机制来配置数据库连接(这样您就可以拥有测试和生产环境) - 有很多方法可以做到这一点,包括Microsoft产品和内部解决方案 - 所以您应该使用相同的方法来配置您的构建计算机。
答案 1 :(得分:1)
在过去六年左右的时间里,我主要使用NHibernate进行持久化。
在单元测试级别上,我使用SQLite内存来测试持久性/实体映射,在集成测试级别上,我使用了真正的数据库服务器(在本地和构建服务器上)。
在这两种情况下,我都使用NHibernate / Fluent NHibernate可以为每个测试创建的脚本设置数据库(之后在集成情况下终止数据库)。这需要更长的时间来运行,但恕我直言,清理代码变坏的风险更糟(顺便说一句,在xUnit测试模式书中有关于此的讨论)。
答案 2 :(得分:0)
我的方法是创建一组集成测试,用于测试数据访问层(存储库和映射)。我认为如果使用ORM工具使用“约定优于配置”方法(如EF中的POCO映射),这一点非常重要。我有DB初始化脚本,它创建新数据库(与当前开发DB相同)并创建初始测试数据集。此脚本仅在测试运行开始时运行一次。在测试运行结束时删除数据库。每个集成测试都使用在测试结束时回滚的事务,因此所有测试的测试数据都相同。要在DB中验证数据,我使用带有标准SqlCommand方法的辅助类。要使用SqlCommand,您必须为测试使用ReadUncommited事务隔离级别,因为您通常不共享SqlCommand和EF上下文之间的连接。