3

我的应用程序中有一个数据访问层,它包装了一个 ADO.NET 数据提供程序。DAL 将数据提供程序返回的数据转换为 .NET 对象。我看过很多建议不要对 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 接口。我将编写一组可以在整个代码库中重复使用的假实现。

人们可以对这个想法提出一些批评吗?是否已经有类似的实现可以用于此?

谢谢

4

1 回答 1

2

我就数据访问类(DAL、DAC、DAO、存储库等)的正确单元测试(不,不是集成测试)这一主题进行了很多哲学争论。有些人认为这是毫无意义的,因为您正在进行集成测试。我发现对这些经常被忽视的代码单元进行单元测试具有巨大的价值。首先,为了正确地对数据访问类进行单元测试,它必须结构正确,并且必须在消费者可能与之交互的沙地上画线——想想接口。数据访问实现应该定义一个接口,它实现了消费应用程序代码仅依赖于该接口。您选择的基础架构代码(ADO.NET、NHibernate、NDatabase 等)应该具有您的数据访问代码仅依赖的接口。使用这些基础设施接口(IDBConnection、ISession、IDatabase 等)可用并正确利用,然后您可以使用您选择的模拟工具在单元测试中模拟这些接口。这为您提供了更高质量的数据访问代码,这些代码已经过单元测试(模拟基础设施接口)、集成测试(针对 REAL 数据库),并且具有较低的网络耦合。

一个注意事项:在我看来,需要警惕的不良代码气味是数据访问相关的代码流过数据访问(或持久性)层时。例如,如果您看到连接、命令、会话等的使用比数据访问类实现更高,则这违反了关注点分离。

于 2011-05-21T04:35:21.303 回答