2010-06-26 223 views
3

This question about unit tests引发了另一件困扰着我的事情。我有三种方式来回敲击数据库时进行单元测试。单元测试和数据库

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

我知道选项1是“正确”的方式做单元测试,而是三个,这可能是我用的最少的(尽管最新的项目已经与国际奥委会的选项,使门对我开放)。我意识到这很大程度上取决于究竟是什么被嘲笑和什么被测试,但我在这里错过了什么?

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

+0

技术#3(自动执行SUT,但手动验证结果)对于测试不能自动验证的事情很有用,如UI的外观和外观,HTML在不同浏览器中的外观或确保你的游戏具有良好的图形。但是,对于数据库,我认为您将花更少的时间来使用前两种技术进行全面测试。 – apollodude217 2010-06-26 14:35:47

+0

这不是一个dup吗? http://stackoverflow.com/questions/3111645/mock-objects-vs-test-database – 2010-06-26 15:45:33

回答

3

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

关于国际奥委会,我认为它目前被过度使用(请注意我的意见在这方面代表了少数程序员)。您可以在测试过程中使用像Moles这样的工具来模拟,而不必滥用程序的设计。我不使用国际奥委会,除非设计真的需要它。

1

这里有一整套答案。首先要做的是清楚地表达你正在测试的内容。它是一个API背后有一个数据库,DAO对象,你的数据库结构?

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

我使用嘲笑相当多,虽然他们伟大的单元测试一个类,在某些情况下,他们不是。他们也很容易错过铅。与mock一起工作的东西并不罕见,在集成时不起作用。原因在于你正在加载模拟的某些期望和回应,你可能从模拟代表的东西中错误地解释了这些。

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

2

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

您也可以使用实际数据库(选项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; 
      } 
     } 
    } 
} 

容易馅饼。

0

你真的测试了什么,这让你觉得这很难吗?

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

单元测试最重要的原理之一是单独解耦和测试。当你清楚了解如何做到这一点时,单元测试很容易。当你不这样做时,单元测试变得很难。