我的应用程序中有一个数据访问层,它包装了一个ADO.NET数据提供程序。 DAL将数据提供程序返回的数据转换为.NET对象。我已经看到很多帖子建议不要对DAL进行单元测试,但它让我担心在那里会出现很多问题 - 有很多循环,转换和空检查。
我对使用RhinoMocks之类的东西创建一个模拟DbProvider有一些想法,但是我在每个测试中必须模拟的接口数量将是压倒性的,并且我必须设置的期望数量将使得测试非常难以阅读。似乎每个测试都比它测试的代码更复杂 - 从单元测试的3个目标的角度来看,这将是一场灾难:
我有一个想法是实现一个友好的DbProviderFactory来从xml加载样本数据。我可以通过测试中的Dependency Injection将其插入。它应该使维护测试更加简单。一个简单的例子可能是:
[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代码。它具有以下优点:
人们会对这个想法提出一些批评吗?我可以使用类似的实现吗?
由于
答案 0 :(得分:2)
我对数据访问类(DAL,DAC,DAO,存储库等)的正确单元测试(不,不是集成测试)的主题进行了很多哲学论证。有些人认为,由于您正在进行集成测试,因此毫无意义。我发现单元测试这些经常被忽略的代码单元具有巨大的价值。首先,为了正确地对数据访问类进行单元测试,它必须正确构造,并且必须在消费者可以交互的沙子中绘制线 - 想想接口。数据访问实现应该定义一个接口,它实现消费应用程序代码只依赖于它。您选择的基础结构代码(ADO.NET,NHibernate,NDatabase等)应该具有您的数据访问代码仅依赖的接口。通过正确使用和利用这些基础结构接口(IDBConnection,ISession,IDatabase等),您可以使用您选择的模拟工具在单元测试中模拟这些接口。这为您提供了更高质量的数据访问代码,这些代码经过了单元测试(模拟基础设施接口),集成测试(针对REAL数据库),并且具有较低的净耦合。
一个注意事项:在我看来,当数据访问相关代码流过数据访问(或持久性)层时,需要警惕的代码异味。例如,如果您看到连接,命令,会话等的使用高于数据访问类的实现,则会出现违反“关注点分离”的情况。