2011-04-13 77 views
3

我在我的应用程序中包含一个ADO.NET数据提供程序的数据访问层。 DAL将数据提供者返回的数据转换为.NET对象。我已经看到很多帖子建议对单元测试DAL,但是它让我很担心,那里可能会出现很多错误 - 有很多循环和投射以及空白检查。你如何测试DAL?

我对创建一个类似RhinoMocks的模拟DbProvider有一些想法,但是在每次测试中我不得不模拟的接口数量会非常多,而且我必须设置的期望数量会使测试非常难以阅读。看来,每个测试会比它的测试代码更复杂 - 这将是一场灾难,从单元测试的3个进球的角度来看:

  1. 可读性
  2. 可维护性
  3. 诚信

我有一个想法,实现友好的DbProviderFactory从XML加载示例数据。我可以通过测试中的依赖注入来插入它。它应该使维护测试变得更简单。一个简单的例子可能是:

[TestCase] 
public void CanGetCustomer() 
{ 
    var expectedCommand = new XmlCommand("sp_get_customer"); 
    expectedCommand.ExpectExecuteDataReader(
     resultSet: @"<customer firstName=""Joe"" lastName=""Blogs"" ... />"); 

    var factory = new XmlProviderFactory(expectedCommand); 

    var dal = new CustomerDal(factory); 
    Customer customer = dal.GetCustomer(); 

    Assert.IsNotNull(customer, "The customer should never be null"); 
    Assert.AreEqual(
     "Joe", customer.FirstName, 
     "The customer had an unexpected FirstName."); 
} 

我觉得这个方法 - 使用友好DbProvider - 可能更容易测试DAL代码。它具有以下优点:

  1. 测试数据将在xml中,并且可以放在源代码控制以及单元测试中。它可能在外部文件中,或在测试中联机。
  2. 我没有使用真正的数据库,所以这消除了有状态问题。因此,在每次测试之前,我不必将数据库置于已知状态。
  3. 我不必在每个测试中嘲笑所有的ADO.NET接口。我将编写一套假实现,我可以在整个代码库中重新使用这些实现。

难道人们会对这个想法提出一些批评吗?有没有类似的实现,我可以使用它?

感谢

回答

2

我到了很多关于数据访问类(DALS,数模转换器,DAO中,库等)进行适当的单元测试(不,不是集成测试)的话题哲学论点。有些人认为,由于您正在进行集成测试,因此毫无意义。我发现对这些经常被忽略的代码单元进行单元测试具有巨大的价值。首先,为了对数据访问类进行适当的单元测试,必须正确地构造它,并且它必须在消费者可能交互的地方绘制线 - 思考接口。数据访问实现应该定义一个接口,它实现了消费应用程序代码仅依赖的接口。您选择的基础架构代码(ADO.NET,NHibernate,NDatabase等)应该具有您的数据访问代码仅依赖于其的接口。通过这些基础设施接口(IDBConnection,ISession,IDatabase等)的正确使用和利用,您可以使用您选择的模拟工具在单元测试中模拟这些接口。这为您提供了更高质量的数据访问代码,这些代码已经过单元测试(模拟基础架构接口),经过集成测试(针对REAL数据库),并且具有更低的网络耦合。

一个注释:在我看来,一个不好的代码气味值得注意的是数据访问相关的代码在数据访问(或持久性)层泄漏。例如,如果您看到连接,命令,会话等对数据访问类实现的使用更高,这意味着违反了分离问题。

+3

我同意你所说的一切。但挑战在于测试与ADO.NET IDbProvider实现交互的代码。我想验证代码可以正确处理空值,空结果集或异常情况。我不想再注入更多的抽象层,因为这只是将问题转移到其他地方。嘲笑ADO.NET很复杂,因为使用了很多实体。 – sheikhjabootie 2011-05-22 14:43:44