3

这个关于单元测试的问题引发了另一件困扰我的事情。在访问数据库时,我反复讨论了三种进行单元测试的方法。

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

我知道选项 1 是进行单元测试的“正确”方式,但在这三个选项中,这可能是我使用最少的选项(尽管最新的项目是 IOC,所以这扇门对我敞开)。我意识到这在很大程度上取决于正在模拟什么以及正在测试什么,但是我在这里缺少什么?

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

4

4 回答 4

3

如果您有一个只公开少数IQueryable<T>方法的数据访问层,那么第一个应该不会那么难。有一个很好的技巧可以用于伪造数据:只需将实体对象存储在 a 中List<T>并使用AsQueryable. 对于数据部分,我发现这比 moq 更容易。

关于 IOC,我认为它目前被过度使用(请注意,我的观点在这方面代表了少数程序员)。您可以在测试期间使用Moles之类的工具进行模拟,而不必滥用程序的设计。除非设计确实需要,否则我不使用 IOC。

于 2010-06-26T14:04:02.217 回答
2

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

您还可能会发现与实际数据库(选项 2)的集成测试也需要使用(选项 2)。为什么?因为真正的单元测试没有涵盖您需要测试的部分内容(O/R 映射、与实际数据库模式的兼容性等)。

至于设置和拆卸逻辑,从这里继承通常就足够了(对数据库使用 .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;
            }
        }
    }
}

非常简单。

于 2010-06-26T14:29:25.573 回答
1

有一整套答案。首先要做的是清楚地阐明你正在测试什么。它是背后有数据库、DAO 对象、您的数据库结构的 API 的外观吗?

做到这一点也将帮助您决定测试事物的最佳方式。我还可以看到您列出的替代方案。那就是在内存数据库(如 hsql)中启动并运行你的类和测试。这意味着您可以在测试开始时创建数据库结构。因为它在内存中,所以您不必担心拥有数据库服务器,它速度很快,并且您可以使用特定于您的测试的数据加载它。

我经常使用模拟,虽然它们非常适合对类进行单元测试,但在某些情况下它们不是。他们也很容易错过领先优势。与模拟一起工作的东西在集成时不起作用并不少见。这样做的原因是您正在加载带有某些期望和响应的模拟,您可能从模拟所代表的事物中错误地解释了它们。

不要误会我的意思,我喜欢模拟并且经常使用它们。但是在这样做的时候,你绝不能假设因为某些东西是单元测试的,所以它是正确的。它确实增加了机会,但在集成测试中实际上给了你 100% 的保证。

于 2010-06-26T14:25:50.980 回答
0

你到底在测试什么让你觉得这很困难?

如果您将业务和服务层逻辑与持久性代码分离,您应该能够轻松地隔离要进行单元测试的代码,而无需使用数据库。

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

于 2010-07-02T14:21:22.020 回答