这个关于单位测试的问题 激发了另一件事困扰我的事情。在击中数据库时,我来回走了三种方法来进行单元测试。

  1. 创建模拟对象并将其插入。这具有不需要数据库的优势,但是它很耗时,我不确定我得到了多少投资回报。我已经有点进入IOC和小号,但似乎仍然很痛苦。
  2. 创建设置和拆卸数据库脚本以创建已知情况,并为这些情况进行测试。同样,可能是时间密集的,但在大多数情况下仍然比模拟对象更容易创建。假设他们在本地主机上有SQL Server,那么在工作中的其他人仍然可以运行它。
  3. 手动检查开发数据库并修改单元测试。大量的手动工作,但是如果我有一个“测试集”不会改变,则似乎可以正常工作。至少在我的机器上:-)。

我知道选项1是进行单元测试的“正确”方法,但是在这三个方法中,这可能是我使用最少的选项(尽管最新的项目与IOC有关,因此该门对我开了)。我意识到其中很多取决于嘲笑什么以及正在测试什么,但是我在这里缺少什么?

如果上下文有帮助,我在C#商店中,编写内部应用程序,只有少数开发人员。

有帮助吗?

解决方案

如果您有一个数据访问层仅显示少数的数据访问层,那么第一个不应该很难 IQueryable<T> 方法。有一个不错的技巧,您可以用于假数据:只需将实体对象存储在一个 List<T> 并使用 AsQueryable. 。我发现与数据部分相比,这比欧洲签名更容易。

关于IOC,我认为它目前已过度使用(请注意,我的意见代表了这方面的少数程序员)。您可以使用类似的工具 在测试过程中嘲笑而无需滥用程序的设计。除非设计实际要求,否则我不使用IOC。

其他提示

我肯定会继续使用真实的单元测试(选项1)。我喜欢斯蒂芬的建议。

您可能还可以找到使用实际数据库的集成测试(选项2) 必要的 也使用(选项2)。为什么?因为您需要测试的部分内容(O/R映射,与实际DB架构的兼容性等)不受真实的单位测试的涵盖。

至于设置和拆卸逻辑,从此基础上继承(使用.NET,NUNIT和SQLSERVER作为数据库):

using System.Transactions;
using NUnit.Framework;
namespace Crown.Util.TestUtil
{
    [TestFixture]
    public class PersistenceTestFixture
    {
        public TransactionScope TxScope { get; private set; }

        [SetUp]
        public void SetUp()
        {
            TxScope = new TransactionScope();
        }

        [TearDown]
        public void TearDown()
        {
            if (TxScope != null)
            {
                TxScope.Dispose();
                TxScope = null;
            }
        }
    }
}

非常简单。

有一套答案。首先要做的就是清楚地阐明您正在测试的内容。它是API的外墙,其背后有数据库,DAO对象,您的数据库结构?

解决此问题也将帮助您确定测试事物的最佳方法。从我可以看到您列出的替代方案的替代方案。那就是在内存数据库(例如HSQL)中启动,并根据此类运行类和测试。这意味着您可以在测试开始时创建数据库结构。因为它在内存中,您不必担心拥有数据库服务器,所以它很快,并且可以加载它的数据特定于测试。

我使用了很多模拟,尽管它们非常适合单位测试课程,但在某些情况下不是。他们也可以很容易地错过铅。与Mocks一起使用的事情并不少见,在集成时不工作。原因是您正在使用某些期望和响应加载模拟,这可能是从模拟所代表的事物中误导了。

不要误会我的意思,我喜欢模拟并使用它们很多。但是这样做,您绝对不能假设因为某物经过单位测试,这是正确的。它确实增加了机会,但是在集成测试中实际上可以为您提供100%的保证。

您正在测试什么,这使您觉得这很困难?

如果您将业务和服务层逻辑从持久代码中解脱出来,则应该能够隔离您要单位测试的代码而无需DB。

单位测试的最重要原理之一是分离和分离测试。当您清楚地了解如何做到这一点时,单位测试很容易。当您不这样做时,单位测试就会变得难。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top