本文是根据 Roy Osherove的《Simplified Database Unit testing using Enterprise Services 》一文的整理而来,源地址如下: http://weblogs.asp.net/rosherove/articles/dbunittesting.aspx
二、常见数据访问层的单元测试方法介绍:
数据访问层一般都是在单个类中存在大量的CRUD(Create, Retrieve, Update, Delete) 方法,一般的测试方法,会带来如下的各种问题。主要有:
1、垃圾数据;2、影响其他的测试;3、会从不知到的状况开始测试。
处理以上问题的常见方法:
三、COM+ Enterprise Services 测试数据访问层
为了解决这些缺点我们的解决方式是利用COM+ Enterprise Services 来测试数据访问层。
首先,利用System.Enterprise Services 及NUnit编写测试用例的基类如下:
namespace TransactionTesting {
[TestFixture]
[Transaction(TransactionOption.Required)]
public class DatabaseFixture:ServicedComponent
{
[TearDown]
public void TransactionTearDown(){
if(ContextUtil.IsInTransaction){
ContextUtil.SetAbort();} }
} }
以上代码的解释如下:
四、该方法的缺陷
一、主题
通过介绍一种在.Net平台上、基于Enterprise Services、NUnit针对数据访问层的单元测试方法,了解与掌握该测试方法的优劣和具体实施方法。
随着软件工程、软件设计技术的发展及实际软件项目或产品的需要,测试技术中的测试工具和方法发生了翻天覆地的变化。出现了测试驱动开发(Test Driven Development ),即将测试方案设计工作提前,在编写代码之前先做这一项工作; 从测试的角度来验证设计,推导设计; 同时将测试方案当作行为的准绳,有效地利用其检验代码编写的每一步,实时验证其正确性,实现软件开发过程的“小步快走“。
在这个思想下,单元测试是TDD的源泉。本篇文章就是对针对数据访问层测试(Data Access Layer)的一种单元测试方法。
通过介绍一种在.Net平台上、基于Enterprise Services、NUnit针对数据访问层的单元测试方法,了解与掌握该测试方法的优劣和具体实施方法。
随着软件工程、软件设计技术的发展及实际软件项目或产品的需要,测试技术中的测试工具和方法发生了翻天覆地的变化。出现了测试驱动开发(Test Driven Development ),即将测试方案设计工作提前,在编写代码之前先做这一项工作; 从测试的角度来验证设计,推导设计; 同时将测试方案当作行为的准绳,有效地利用其检验代码编写的每一步,实时验证其正确性,实现软件开发过程的“小步快走“。
在这个思想下,单元测试是TDD的源泉。本篇文章就是对针对数据访问层测试(Data Access Layer)的一种单元测试方法。
二、常见数据访问层的单元测试方法介绍:
数据访问层一般都是在单个类中存在大量的CRUD(Create, Retrieve, Update, Delete) 方法,一般的测试方法,会带来如下的各种问题。主要有:
1、垃圾数据;2、影响其他的测试;3、会从不知到的状况开始测试。
处理以上问题的常见方法:
1、在测试代码中Undo你的CRUD方法。
2、手工删除(最普遍的方法):这样做会在每个测试用例结束时,加入于你的测试相反的操作方法。该方法会带来如下问题:a、相反的操作方法没有现成的方法(需要你自己写存储过程或ADO.Net类);b、写的删除方法不能完全保证其是否有BUG; c、方法可能会破坏数据的完整性(数据关系不对,数据全部删除了)。
3、利用ADO.Net中的事务对象实现:在每个测试中利用事务及回滚处理你的每个数据操作。该方法会带来如下问题:a、你需要担心你的测试用例中的事务对象对被测试的方法中包含的内部事务的影响。(利用命令模式可以解决这个问题,见James Newkirk 著作《Test Drivern Development with Micrsoft.Net》)包含很多的事务管理类 )。
3、利用ADO.Net中的事务对象实现:在每个测试中利用事务及回滚处理你的每个数据操作。该方法会带来如下问题:a、你需要担心你的测试用例中的事务对象对被测试的方法中包含的内部事务的影响。(利用命令模式可以解决这个问题,见James Newkirk 著作《Test Drivern Development with Micrsoft.Net》)包含很多的事务管理类 )。
三、COM+ Enterprise Services 测试数据访问层
为了解决这些缺点我们的解决方式是利用COM+ Enterprise Services 来测试数据访问层。
首先,利用System.Enterprise Services 及NUnit编写测试用例的基类如下:
namespace TransactionTesting {
[TestFixture]
[Transaction(TransactionOption.Required)]
public class DatabaseFixture:ServicedComponent
{
[TearDown]
public void TransactionTearDown(){
if(ContextUtil.IsInTransaction){
ContextUtil.SetAbort();} }
} }
以上代码的解释如下:
1、基类继承于TransactionOption.Required(它利用了COM+的自动事务处理)
2、用[TestFixture]与Transaction(TransactionOption.Required)]两个属性,能使这个类的初始化及调用时,COM+将自动化创造一个事务上下文对象,并加入已存在的事务列表中。
3、在TearDown方法中调用ContextUtil.SetAbort()。
4、注意测试项目必须有一个强名称。
以上操作后,会发生:
1、在每个测试前,事务上下文对象打开,并把测试类加入到已存在的事务中;
2、测试被执行;
3、测试结束时,TearDown方法被执行,事务被回滚。
其次,设置强名称。
用SN.exe –K 创建密码文件,在测试项目中打开AssemblyInfo.cs 设置属性[assembly: AssemblyKeyFile(@"..\..\..\test.snk")] ;设置静态的Version属性 ,修改“1.0.*”为[assembly: AssemblyVersion("1.0.0")] 。
然后,编写测试代码
测试类需要继承上面编写的DatabaseFixture,其他的测试方法按照NUnit规定的编写即可。
2、用[TestFixture]与Transaction(TransactionOption.Required)]两个属性,能使这个类的初始化及调用时,COM+将自动化创造一个事务上下文对象,并加入已存在的事务列表中。
3、在TearDown方法中调用ContextUtil.SetAbort()。
4、注意测试项目必须有一个强名称。
以上操作后,会发生:
1、在每个测试前,事务上下文对象打开,并把测试类加入到已存在的事务中;
2、测试被执行;
3、测试结束时,TearDown方法被执行,事务被回滚。
其次,设置强名称。
用SN.exe –K 创建密码文件,在测试项目中打开AssemblyInfo.cs 设置属性[assembly: AssemblyKeyFile(@"..\..\..\test.snk")] ;设置静态的Version属性 ,修改“1.0.*”为[assembly: AssemblyVersion("1.0.0")] 。
然后,编写测试代码
测试类需要继承上面编写的DatabaseFixture,其他的测试方法按照NUnit规定的编写即可。
四、该方法的缺陷
1、需要ADO.Net驱动支持分布式的事务(如对MS- Acess不支持)
2、被测试的方法本身利用了Enterprise Services,并设置了Transaction attribute (“Disabled”、 “Not Supported”、 "Requires New")。
2、被测试的方法本身利用了Enterprise Services,并设置了Transaction attribute (“Disabled”、 “Not Supported”、 "Requires New")。
3、被测试的方法本身有不参与分布式事务的DDL语句(用语定义和管理数据库中的对象,如Create,Alter和Drop,因为DDL操作是隐性提交的不能Rollback )。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现