我如何unit testing持久性?
作为一个实践testing驱动开发的新手,我经常会对如何将持久性unit testing到一个数据库感到尴尬。
我知道在技术上这将是一个集成testing(而不是unit testing),但我想找出以下的最佳策略:
- testing查询。
- testing插入。 如何知道如果插入失败了? 我可以通过插入然后查询来testing它,但是怎样才能知道查询没有错?
- testing更新和删除 – 与testing插入相同
做这些的最佳做法是什么?
关于testingSQL:我知道这可以做到,但是如果我使用像NHibernate这样的O / R映射器,它会在用于输出查询的别名中附加一些命名瑕疵,因为这有点不可预知,我不确定我可以testing。
我应该放弃一切,只要相信NHibernate? 我不确定这是谨慎的。
看看DB单元。 这是一个Java库,但必须有一个C#等价物。 它使您可以使用一组数据来准备数据库,以便知道数据库中的内容,然后可以与DB Unit进行交互,以查看数据库中的内容。 它可以运行在许多数据库系统上,所以你可以使用你的实际的数据库设置,或者使用其他的东西,比如Java中的HSQL(带有内存选项的Java数据库实现)。
如果你想testing你的代码是否正确地使用了数据库(你很可能应该这样做),那么这是隔离每个testing并确保数据库预期数据准备好的方法。
正如迈克斯通所说 ,DbUnit非常适合在运行testing之前使数据库进入已知状态。 当您的testing完成后,DbUnit可以将数据库恢复到运行testing之前的状态。
DbUnit(Java)
DbUnit.NET
你可以通过模拟数据库连接来进行unit testing。 这样,您就可以构build方法调用stream程中的特定查询成功或失败的场景。 我通常build立我的模拟期望,以便实际的查询文本被忽略,因为我真的想testing方法的容错性以及它如何处理自己 – SQL的具体细节与此无关。
显然这意味着你的testing不会真正validation该方法的工作原理 ,因为SQL可能是错误的。 这就是集成testing的起点。为此,我希望别人能有一个更彻底的答案,因为我刚刚开始掌握这些。
我在这里写了一篇关于unit testing数据层的文章 ,其中涵盖了这个确切的问题。 (可耻的)插头道歉,但文章太长,不能张贴在这里。
我希望能帮到你 – 在过去的6个月里,我在3个活跃的项目上工作得非常好。
问候,
Rob G
我unit testing持久性时遇到的问题,特别是没有ORM,因此嘲笑你的数据库(连接),你不知道你的查询是否成功。 这可能是因为你的查询是专门为特定的数据库版本devise的,只能使用该版本。 如果你嘲笑你的数据库你永远不会发现。 所以在我看来,unit testing的持久性是有限的使用。 您应该始终添加针对目标数据库运行的testing。
对于NHibernate,我肯定会主张嘲笑unit testing的NHibernate API – 相信库做正确的事情。 如果你想确保数据真正进入数据库,请执行集成testing。
对于基于JDBC的项目,可以使用Acolyte框架: http : //acolyte.eu.org 。 它允许模拟想要testing的数据访问,从JDBC抽象中受益,而无需pipe理特定的testing数据库。
我也嘲笑数据库,并检查查询是你所期望的。 有testing检查错误的sql的风险,但是这将在集成testing中被检测到
技术上持久性的unit testing不是unit testing,而是集成testing。
用C#使用mbUnit,只需使用SqlRestoreInfo和RollBack属性
[TestFixture] [SqlRestoreInfo(<connectionsting>, <name>,<backupLocation>] public class Tests { [SetUp] public void Setup() { } [Test] [RollBack] public void TEST() { //test insert. } }
在NUnit中也可以做到这一点,excpet的属性名称略有不同。
至于检查你的查询是否成功,你通常需要按照第二个查询来查看数据库是否已经如你所期望的那样改变了。
我通常创build一个存储库,并使用它来保存我的实体,然后检索一个新的。 然后我断言检索的是等于保存的。