【问题标题】:How do I unit test persistence?如何对持久性进行单元测试?
【发布时间】:2008-08-05 09:43:01
【问题描述】:

作为一名实践测试驱动开发的新手,我经常陷入困境,即如何对数据库的持久性进行单元测试。

我知道从技术上讲这将是一个集成测试(不是单元测试),但我想找出以下最佳策略:

  1. 测试查询。
  2. 测试插件。如果插入失败,我怎么知道插入出错了?我可以通过插入然后查询来测试它,但是我怎么知道查询没有错呢?
  3. 测试更新和删除 -- 与测试插入相同

执行这些操作的最佳做​​法是什么?


关于测试 SQL:我知道这是可以做到的,但是如果我使用像 NHibernate 这样的 O/R 映射器,它会在用于输出查询的别名中附加一些命名缺陷,因为这有点不可预测我'我不确定我是否可以对此进行测试。

我应该放弃一切,只相信 NHibernate 吗?我不确定这是否谨慎。

【问题讨论】:

    标签: sql-server unit-testing tdd


    【解决方案1】:

    查看数据库单元。它是一个 Java 库,但必须有一个 C# 等价物。它使您可以使用一组数据准备数据库,以便您了解数据库中的内容,然后您可以与 DB Unit 交互以查看数据库中的内容。它可以针对许多数据库系统运行,因此您可以使用实际的数据库设置,或使用其他东西,例如 Java 中的 HSQL(具有内存选项的 Java 数据库实现)。

    如果您想测试您的代码是否正确使用数据库(您很可能应该这样做),那么这是隔离每个测试并确保数据库已准备好预期数据的方法。

    【讨论】:

      【解决方案2】:

      作为Mike Stone said,DbUnit 非常适合在运行测试之前让数据库进入已知状态。完成测试后,DbUnit 可以将数据库恢复到运行测试之前的状态。

      DbUnit (Java)

      DbUnit.NET

      【讨论】:

        【解决方案3】:

        您通过模拟数据库连接来进行单元测试。这样,您可以构建方法调用流中的特定查询成功或失败的场景。我通常构建我的模拟期望,以便忽略实际的查询文本,因为我真的想测试方法的容错性以及它如何处理自身——SQL 的细节与此无关。

        显然,这意味着您的测试实际上不会验证方法有效,因为 SQL 可能是错误的。这就是集成测试开始的地方。为此,我希望其他人会有更全面的答案,因为我自己才刚刚开始掌握这些。

        【讨论】:

          【解决方案4】:

          我在这里写了一篇关于unit testing the data layer 的帖子,其中涵盖了这个确切的问题。为(可耻的)插件道歉,但文章太长,无法在此处发布。

          希望对您有所帮助 - 在过去 6 个月中,它在 3 个活跃项目中对我来说非常有效。

          问候,

          罗伯克

          【讨论】:

            【解决方案5】:

            我在对持久性进行单元测试时遇到的问题,尤其是在没有 ORM 并因此模拟您的数据库(连接)的情况下,您并不真正知道您的查询是否成功。可能是您的查询是专门为特定数据库版本设计的,并且仅在该版本上成功。如果你模拟你的数据库,你永远不会发现这一点。因此,在我看来,单元测试持久性的用途有限。您应该始终添加针对目标数据库运行的测试。

            【讨论】:

            • 我同意,虽然我从来都不是 TDD 纯粹主义者,但我肯定看到了 TDD 的很多好处,但忽略现实,不真正测试进出数据库的记录,你不知道您的应用程序真正要在野外做什么。在我得到分配给我的“错误”之前,我的代码无法正常工作,我运行了我的单元测试并发现另一个开发人员踩到了我的 sproc(evil evil sprocs)并且从不关心运行我的单元测试看他们破坏了整个系统。
            【解决方案6】:

            对于NHibernate,我肯定会提倡在单元测试中模拟NHibernate API——相信库会做正确的事情。如果您想确保数据真正进入数据库,请进行集成测试。

            【讨论】:

              【解决方案7】:

              对于基于 JDBC 的项目,可以使用我的 Acolyte 框架:http://acolyte.eu.org。它允许模拟您想要测试的数据访问,受益于 JDBC 抽象,而无需管理特定的测试数据库。

              【讨论】:

                【解决方案8】:

                我还会模拟数据库,并检查查询是否符合您的预期。存在测试检查错误 sql 的风险,但这会在集成测试中检测到

                【讨论】:

                  【解决方案9】:

                  我通常创建一个存储库,用它来保存我的实体并检索一个新的。然后我断言检索到的等于保存的。

                  【讨论】:

                    【解决方案10】:

                    从技术上讲,持久性单元测试不是单元测试。它们是集成测试。

                    对于使用 mbUnit 的 C#,您只需使用 SqlRestoreInfoRollBack 属性:

                        [TestFixture]
                        [SqlRestoreInfo(<connectionsting>, <name>,<backupLocation>]
                        public class Tests
                        {
                          
                            [SetUp]
                            public void Setup()
                            {
                            
                            }
                    
                            [Test]
                            [RollBack]
                            public void TEST()
                            {
                               //test insert. 
                            }
                        }
                    

                    在 NUnit 中也可以这样做,只是属性名称略有不同。

                    至于检查,如果您的查询成功,您通常需要在其后进行第二次查询,以查看数据库是否已按预期更改。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-09-29
                      • 1970-01-01
                      • 2012-01-08
                      • 2019-11-02
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-09-11
                      相关资源
                      最近更新 更多