去年夏天,我开发了一个基本的ASP.NET / SQL Server CRUD应用程序,单元测试是其中一个要求。 当我尝试对数据库进行测试时遇到了一些麻烦。 根据我的理解,单元测试应该是:

  • 无国籍
  • 相互独立
  • 可重复的,具有相同的结果,即没有持久的变化

在开发数据库时,这些要求似乎彼此不一致。 例如,我无法在不确定要插入的行的情况下测试Insert(),因此我需要先调用Delete()。 但是,如果他们还没有呢? 然后我需要先调用Exists()函数。

我最终的解决方案涉及非常大的设置功能(哎呀!)和一个空的测试用例,它将首先运行并指示设置运行没有问题。 这是牺牲测试的独立性,同时保持他们的无国籍状态。

我找到的另一个解决方案是将函数调用包装在一个可以轻松回滚的事务中,比如Roy Osherove的XtUnit 这项工作,但它涉及另一个库,另一个依赖,并且对于手头的问题似乎有点太沉重的解决方案。

那么,在面对这种情况时,SO社区做了什么?


tgmdbm说:

您通常使用自己喜欢的自动单元测试框架来执行集成测试,这就是为什么有些人会感到困惑,但他们不遵循相同的规则。 您可以参与许多课程的具体实施(因为它们已经过单元测试)。 您正在测试具体类如何与彼此以及与数据库交互

因此,如果我正确地阅读此内容,则无法有效地对数据访问层进行单元测试。 或者,数据访问层的“单元测试”是否涉及测试,例如,由类生成的SQL /命令,而不依赖于与数据库的实际交互?

===============>>#1 票数:25 已采纳

除了断言表存在,包含预期的列以及具有适当的约束之外,没有真正的单元测试数据库的方法。 但这通常不值得做。

您通常不会对数据库进行单元测试。 您通常将数据库纳入集成测试。

您通常使用自己喜欢的自动单元测试框架来执行集成测试,这就是为什么有些人会感到困惑,但他们不遵循相同的规则。 您可以参与许多课程的具体实施(因为它们已经过单元测试)。 您正在测试具体类如何与彼此以及与数据库交互。

===============>>#2 票数:11

DBUnit的

您可以使用此工具在给定时间导出数据库的状态,然后在进行单元测试时,可以在测试开始时自动回滚到其先前的状态。 我经常在工作的地方使用它。

===============>>#3 票数:5

单元测试中外部依赖关系的常用解决方案是使用模拟对象 - 也就是说,模仿您正在测试的真实对象的行为的库。 这并不总是直截了当,有时需要一些聪明才智,但如果您不想“自己动手”,那么.Net有几个好的(免费软件)模拟库。 立即想到两个:

Rhino Mocks是一个声誉很好的公司。

NMock是另一个。

还有很多商业模拟库。 编写好的单元测试的一部分实际上是为它们设计代码 - 例如,通过使用有意义的接口,这样你就可以通过实现其界面的“假”版本来“模拟”一个依赖对象。可预测的方式,用于测试目的。

在数据库模拟中,这意味着“模拟”您自己的数据库访问层,其中的对象返回组成的表,行或数据集对象,供您的单元测试处理。

在我工作的地方,我们通常从头开始创建自己的模拟库,但这并不意味着你必须这样做。

===============>>#4 票数:4

是的,您应该重构代码以访问访问数据库的存储库和服务,然后您可以模拟或存根这些对象,以便测试对象永远不会触及数据库。 这比存储数据库的状态并在每次测试后重置它快得多!

我强烈推荐Moq作为你的模拟框架。 我用过Rhino Mocks和NMock。 Moq非常简单,解决了我对其他框架的所有问题。

===============>>#5 票数:2

我有同样的问题,并且得到了与其他答案者相同的基本结论:不要打扰单元测试实际的数据库通信层,但是如果你想对你的模型函数进行单元测试(以确保它们正在拉动)数据正确,格式正确,等等),使用某种虚拟数据源和设置测试来验证正在检索的数据。

我也发现单元测试的简单定义不适合许多Web开发活动。 但是这个页面描述了一些更“先进”的单元测试模型,可能有助于激发一些在各种情况下应用单元测试的想法:

单元测试模式

===============>>#6 票数:2

我解释说,我一直在使用这个特别的情况的技术在这里

基本思想是在DAL中运行每个方法 - 断言结果 - 当每个测试完成时,回滚以便数据库干净(没有垃圾/测试数据)。

您可能找不到“唯一”的唯一问题是我通常会进行整个CRUD测试(从单元测试的角度来看不是纯粹的),但是这个集成测试允许您查看CRUD +映射代码。 这种方式如果它打破了你就会知道你启动应用程序之前(当我试图快速运行时节省了大量的工作)

===============>>#7 票数:1

您应该做的是从脚本生成的数据库的空白副本运行测试。 您可以运行测试然后分析数据,以确保它在测试运行后具有应有的功能。 然后你只需删除数据库,因为它是一次性的。 这一切都可以自动化,并且可以被视为原子动作。

===============>>#8 票数:1

一起测试数据层和数据库,为项目后期留下了一些惊喜。 但是针对数据库的测试存在问题,主要的一个问题是你正在测试许多测试所共享的状态。 如果在一次测试中向数据库中插入一行,则下一个测试也可以看到该行。
您需要的是一种回滚您对数据库所做更改的方法。
TransactionScope类足够智能,可以处理非常复杂的事务,以及嵌套事务,其中您的测试代码调用在其自己的本地事务上提交。 这是一段简单的代码,显示了为测试添加回滚功能是多么容易:

    [TestFixture]
    public class TrannsactionScopeTests
    {
        private TransactionScope trans = null;

        [SetUp]
        public void SetUp()
        {
            trans = new TransactionScope(TransactionScopeOption.Required);
        }

        [TearDown]
        public void TearDown()
        {
            trans.Dispose();
        }

        [Test]
        public void TestServicedSameTransaction()
        {
            MySimpleClass c = new MySimpleClass();
            long id = c.InsertCategoryStandard("whatever");
            long id2 = c.InsertCategoryStandard("whatever");
            Console.WriteLine("Got id of " + id);
            Console.WriteLine("Got id of " + id2);
            Assert.AreNotEqual(id, id2);
        }
    }

===============>>#9 票数:0

如果您使用LINQ to SQL作为ORM,那么您可以即时生成数据库(前提是您有足够的访问权来自用于单元测试的帐户)。 http://www.aaron-powell.com/blog.aspx?id=1125

  ask by pbh101 translate from so

未解决问题?本站智能推荐:

1回复

使用EF的单元测试数据库

一个单元如何测试连接到数据库的服务? 我在数据访问层中有一个playerRepository类,它直接与数据库进行交互;在业务层中,它有一个playerService类,它创建一个playerRepository实例,并为诸如删除播放器,保存播放器,获取所有播放器, ID /名称yadda
2回复

单元测试数据库访问层

我知道这个问题已经被问过很多次了,但是我有一些具体的代码示例,我想知道对它们进行单元测试是否有意义: 对上述代码进行单元测试是否有意义,以及如何进行此测试。 这里有两个复杂的因素: 数据库本身并不简单,我目前没有简单的方法来创建包含所有测试数据的数据库 模式在不断发展
3回复

如何单元测试数据库类

这可能已被多次询问,但在这里: 我有一个充满数据库连接的类 打开连接 查询数据库 读取值 密切联系 我该如何对这些东西进行单元测试? 我需要创建一个假数据库吗? 我想我可以模拟MySql类(对于c#),但这也是很多工作。 有些陈述是“INSERT IN
2回复

单元测试数据库交互器

我有一个数据库交互组件,除其他外,它具有Writer和Reader类。 writer类具有write方法,例如insertEntity(Entity)和updateEntity(Entity),而Reader类具有诸如getEntityById(EntityId)的方法。 为了实现此组件
2回复

单元测试数据库方法

我即将为新的Web应用程序编写单元测试。 我首选的方法是测试实时数据库结构而不是内存数据库。 据我所知,我可以将我的单元测试数据库调用包含在未提交的事务中。 我认为更好的方法是在初始化测试之前复制实时数据库,并允许事务提交到测试数据库。 如果测试以正确的顺序运行,这将允许我通
1回复

生成复杂数据库(EAV)的单元测试数据

我正在使用遗留应用程序,该应用程序使用了众所周知/可怕的数据建模模式(称为EAV)。 这使得选择在DAL的单元测试期间难以使用的数据生成策略。 为什么? 因为,除了表之间的正常Fk / Pk约束(我们在可能时使用),还有其他关系/约束,只有应用层知道并强制执行。 根据这篇文章 ,最容
1回复

如何在C#中单元测试数据库方法?

我到处搜索过,但是没有发现适合我当前的情况。 我有一个有助于数据库连接的类,我需要对其一些方法进行单元测试: 我知道我不应该从测试中访问数据库。 我尝试使用模拟对象,但我不认为他们可以在这里提供帮助,因为我无法从类外部更改textCommand 。 我尝试建立一个SQLite数
5回复

如何单元测试数据库依赖行为C#

我有一个与DB通信的C#应用​​程序。 我想测试一些依赖于DB的函数。 所以我想确保DB在每次测试运行之前都有一个初始状态。 我使用NUnit来测试我的应用程序。 有什么方法可以恢复DB的初始状态? 谢谢您的帮助!
2回复

单元测试数据库

我想测试我的数据库作为一组集成测试的一部分。 为了提高速度,我已经对我的所有代码单元进行了测试,但是我需要确保所有存储过程和代码在保持时都能正常工作。 昨天我做了一些谷歌搜索,在这里发现了一篇不错的文章http://msdn.microsoft.com/en-us/magazine/cc16
1回复

我可以使用哪种单元测试框架来测试数据库中的数据质量

我有一个数据库,通过它我们可以通过应用计数等显示分组报告。我只需要有一个最好的单元测试框架,它可以帮助我自动查询数据库并验证结果。