东风31 2007-6-25 16:04
关于BIZ层单元测试的一些想法
[color=#000000][font=宋体][size=9pt] 在进行单元测试的时候,对于[/size][/font][size=9pt][font=Times New Roman]Biz[/font][/size][font=宋体][size=9pt]层的测试有个难点:[/size][/font][size=9pt][font=Times New Roman]Biz[/font][/size][font=宋体][size=9pt]层的实现大部分都依赖于[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]层的对象,也依赖于最[/size][/font][/color]
[color=#000000][font=宋体][size=9pt]底层[/size][/font][/color][color=#000000][font=宋体][size=9pt]的数据。对于[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]的依赖我们可以通过[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]的单元测试来确保[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]层的实现是正确的。但是,对于数据的依赖,[/size][/font][/color]
[color=#000000][font=宋体][size=9pt]我们如何来确信我们所依赖的数据是确定的、可信的呢?[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]问题在于,我们的数据大部分情况下都是通过[/size][/font][size=9pt][font=Times New Roman]DBMS[/font][/size][font=宋体][size=9pt]来管理的,应用程序通过访问[/size][/font][size=9pt][font=Times New Roman]DBMS[/font][/size][font=宋体][size=9pt]来操作数据。数据并不由应用程序直接控制,也就是说,我们可以访问、修改数据,但我们无法防止其他人对数据的修改(从程序层面上来讲)。当然,这可以通过我们自己构建一个新的、完全由我们自己操作的数据库来间接实现对数据的完全控制。但是,还有一个问题,在进行单元测试的时候,会有许多类会操作数据,而这些操作可能会改变数据。那么我在实现一个测试的时候,如何保证测试执行之前,测试数据是已知的、确定的。在测试之后,又如何还原到初始状态呢?毕竟,我可不想在写一个单元测试的时候,还要去考虑,其他的测试方法在本方法执行之前执行,数据有什么变化或问题。[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]所以,我希望有一个组件,能够帮助我固化样本数据,能够模拟数据操作[/size][/font][size=9pt][font=Times New Roman](read[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]update[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]delete[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]insert)[/font][/size][font=宋体][size=9pt],能够在运行测试之前装载样本数据并且能够在运行之后将样本数据还原到初试状态。[/size][/font][/color]
[color=#000000][b][size=12pt][font=Times New Roman] [/font][/size][/b][font=宋体][size=9pt]整个系统分为[/size][/font][size=9pt][font=Times New Roman]3[/font][/size][font=宋体][size=9pt]部分:以[/size][/font][size=9pt][font=Times New Roman]Xml[/font][/size][font=宋体][size=9pt]形式存放的样本数据以及相互的关系、一个虚拟数据中心[/size][/font][size=9pt][font=Times New Roman]---[/font][/size][font=宋体][size=9pt]这个中心能够读取[/size][/font][size=9pt][font=Times New Roman]Xml[/font][/size][font=宋体][size=9pt]中的样本数据和相互关系、能够模拟数据操作、能够在期望的时候重新初始化样本数据。最后一部分为[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]层对象对应的[/size][/font][size=9pt][font=Times New Roman]Mock[/font][/size][font=宋体][size=9pt]对象。[/size][/font][size=9pt][/size][/color]
[color=#000000][font=Wingdings][size=9pt][img=9,9]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image001.gif[/img]
[/size][/font][font=宋体][size=9pt]第一部分:将样本数据以及数据之间的关系[/size][/font][size=9pt][font=Times New Roman]Xml[/font][/size][font=宋体][size=9pt]化。[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]对于数据的固化而言,[/size][/font][size=9pt][font=Times New Roman]XML[/font][/size][font=宋体][size=9pt]是最好的选择。但为了系统的扩展性,设计的时候,还是应该秉持[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]纯虚构[/size][/font][size=9pt][font=Times New Roman]GRASP[/font][/size][font=宋体][size=9pt]原则。[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]这一部分的主要功能是,根据用户提供的连接字符串,读取目标数据库的[/size][/font][size=9pt][font=Times New Roman]Schema[/font][/size][font=宋体][size=9pt],并以[/size][/font][size=9pt][font=Times New Roman]XML[/font][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]的形式固化他们。这里的数据库的[/size][/font][size=9pt][font=Times New Roman]Schema[/font][/size][font=宋体][size=9pt]包括表、字段、视图、主键、外键、唯一约束。为了帮助[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]用户组织样本数据,系统还应该提供友好的界面来辅助用户组织样本数据并持久化到[/size][/font][size=9pt][font=Times New Roman]XML[/font][/size][font=宋体][size=9pt]文件中。[/size][/font][size=9pt][/size][/color]
[color=#000000][font=Wingdings][size=9pt][img=9,9]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image001.gif[/img]
[/size][/font][font=宋体][size=9pt]第二部分:虚拟数据中心[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]此部分为组件的核心部分,也是编写单元测试时需要调用的部分。作为虚拟数据中心,需要承[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]担的责任有:[/size][/font][size=9pt][/size][/color]
[size=9pt][font=Times New Roman][color=#000000]1.
[/color][/font][/size][color=#000000][font=宋体][size=9pt]从[/size][/font][size=9pt][font=Times New Roman]Xml[/font][/size][font=宋体][size=9pt]中装载样本数据以及数据之间的关系。[/size][/font][size=9pt][/size][/color]
[size=9pt][font=Times New Roman][color=#000000]2.
[/color][/font][/size][font=宋体][size=9pt][color=#000000]模拟对样本数据的[/color][/size][/font][size=9pt][font=Times New Roman]read[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]update[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]insert[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]delete[/font][/size][color=#000000][font=宋体][size=9pt]操作。并且所执行的这些操作不能违背已存在的数据关联。也就是说不能破坏样本数据的完整性。[/size][/font][size=9pt][/size][/color]
[size=9pt][font=Times New Roman][color=#000000]3.
[/color][/font][/size][color=#000000][font=宋体][size=9pt]回滚对样本数据的操作,使得样本数据恢复到初始状态。[/size][/font][size=9pt][/size][/color]
[size=9pt][font=Times New Roman][color=#000000]4.
[/color][/font][/size][color=#000000][font=宋体][size=9pt]当样本数据被破坏时,可以重新装载样本数据以及数据之间的关系。[/size][/font][size=9pt][/size][/color]
[color=#000000][font=宋体][size=9pt]为了便于管理以及降低复杂度,虚拟数据中心封装装载数据及关系的[/size][/font][size=9pt][font=Times New Roman]DataSet[/font][/size][font=宋体][size=9pt]([/size][/font][size=9pt][font=Times New Roman]has a [/font][/size][font=宋体][size=9pt]方式),仅[/size][/font][size=9pt][/size][/color]
[font=宋体][size=9pt][color=#000000]暴露出一些由虚拟数据中心提供的属性和方法来操作数据。同时,因为虚拟数据中心还不够成熟,因此,提供以两个下划线开头的名为[/color][/size][/font][size=9pt][font=Times New Roman]__InnerDataSet[/font][/size][font=宋体][size=9pt]的[/size][/font][color=#000000][font=宋体][size=9pt]属性来直接操作数据,但不建议这么直接操作,除非您十分熟悉框架结构并且虚拟数据中心提供的方法无法实现您的目的的时候才这么做。[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]所有从虚拟数据中心方法或属性返回的[/size][/font][size=9pt][font=Times New Roman]DataTable[/font][/size][font=宋体][size=9pt]、[/size][/font][size=9pt][font=Times New Roman]DataSet[/font][/size][font=宋体][size=9pt]等对象都是虚拟数据中心内部对象的深拷贝对象,也就是说,操作这些返回值对象并不会影响虚拟数据中心中的数据。只有当直接调用虚拟数据中心提供的方法时,才会影响数据。[/size][/font][size=9pt][/size][/color]
[color=#000000][font=Wingdings][size=9pt][img=9,9]file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image001.gif[/img]
[/size][/font][font=宋体][size=9pt]第三部分:[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]层对象的[/size][/font][size=9pt][font=Times New Roman]Mock[/font][/size][font=宋体][size=9pt]对象。[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman]
[/font][/size][font=宋体][size=9pt]当我们在写[/size][/font][size=9pt][font=Times New Roman]Biz[/font][/size][font=宋体][size=9pt]层的单元测试时,并不是直接操作模拟数据中心来进行检验。我们现实中的[/size][/font][size=9pt][font=Times New Roman]Biz[/font][/size][/color][color=#000000][font=宋体][size=9pt]层的实现是基于[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]之上的。因此,正确的方式是对于每一个[/size][/font][size=9pt][font=Times New Roman]Dal[/font][/size][font=宋体][size=9pt]层的对象定义一个对应的[/size][/font][size=9pt][font=Times New Roman]Mock[/font][/size][font=宋体][size=9pt]对[/size][/font][font=宋体][size=9pt]象来模拟它。[/size][/font][size=9pt][/size][/color]
[color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]其实,本部分并不属于数据模拟中心组件。但组件所提供的功能都是为了本部分服务的,所以[/size][/font][/color][color=#000000][size=9pt][font=Times New Roman] [/font][/size][font=宋体][size=9pt]也拿出来特别说明一下。[/size][/font][size=9pt][/size][/color]
[color=#000000][b][size=12pt][font=Times New Roman] [/font][/size][/b][/color]