DAL即Data Access Layer,在多层的企业应用里面它的作用是与数据库直接打交道,最基本的CRUD(Create, Retrieve, Update, Delete)操作都是在这个层次上完成。和其它的模块不同,对DAL进行单元测试面临不少的困难:
1. 测试过程常常会产生垃圾数据,这些数据可能导致各个Test Case之间互相影响,从而无法保证“Test Case必须独立”这条单元测试的黄金法则。
2. 测试环境难以准备。有些操作的precondition比较复杂,比如添加记录需要有特定的外键存在,一些复杂查询需要大量的测试记录,等等。
3. 难以验证测试结果的正确性。举个简单的例子,对于简单的INSERT操作,如何验证数据已经被正确地插入了呢?再次使用SELECT进行查询吗?如果查询操作本身存在问题,那结果就完全没有意义了。对于一些更复杂的方法,比如多表的修改,复杂条件查询等,更加难以验证结果是否正确。可能这个问题不仅仅是存在于数据库应用测试,而是TDD(Test Driven Development)本身难以克服的一个困难。
今天在TSS.NET上面看到这样的一篇文章:Simplified Database Unit testing using Enterprise Services (by Roy Osherove),里面针对于上面提到的第一个问题,提出了一种基于COM+自动事务的解决方法。这个方法很简单,使用这样的一个类,作为所有数据库应用TestFixture的基类:
using System;
using NUnit.Framework;
using System.EnterpriseServices;
namespace TransactionTesting
{
[TestFixture]
[Transaction(TransactionOption.Required)]
public class DatabaseFixture:ServicedComponent
{
[TearDown]
public void TransactionTearDown()
{
if(ContextUtil.IsInTransaction)
{
ContextUtil.SetAbort();
}
}
}
}
关键的地方在于TearDown的时候,把整个Transaction卷回了,从而避免了各个Test Case之间测试数据的互相影响。当然,这样做的代价也不小,每个Test Fixture必须成为一个Enterprise Serviced Component,于是也就面临着Strong Name, Deployment, DTC Control, Disposing等所有ESC可能面临的问题,但至少,这个方法巧妙地,部分解决了DAL单元测试的困难。
浙公网安备 33010602011771号