开发过程中,数据环境会像某人身材那样迅速走样,使测试的结果随之改变。无论是开发人员还是单元测试,都希望数据环境稳定在某个状态。一个方法是写SQL语句来维护,delete * from foo; insert foo (...) values (...),另外一个方法就是非法雇用DBUnit来干这事, Appfuse现在也这么干了。DBUnit可以把预设的数据倒在一个XML文件里,通过简单的ant指令完成维和任务: <project name="MyProject" default="import" basedir="."> <taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"/> <target name="import"> <dbunit driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/hr" userid="hr" password="hr" supportBatchStatement="true"> <classpath><pathelement location="C:\mysql-con-3.0.11.jar"/></classpath> <operation type="CLEAN_INSERT" src="data.xml"/> </dbunit> </target> </project>
整段的关键是<operation>语句共6种类型,其中CLEAN_INSERT是更彻底的恢复原样,我们主要的维和手段,不过在很多外键很多的时候有点麻烦,要注意表的排列顺序, dbunit是从xml文件的最后删起的.
预设数据可以是手工写就的,也可以从数据库中倒出。怎么看,维护这个XML都比维护长长的SQL语句强。 下面语句不管三七二一,导出全部table。 <dbunit ...> <export dest="export.xml"/> </dbunit>
下面语句导出一个由查询语句产生的DataSet和一个table。 <dbunit ...> <export dest="partial.xml"> <query name="FOO" sql="SELECT * FROM FOO WHERE last_name='Marquiss'"/> <table name="FOO123"/> </export> </dbunit>
说是非法雇用,因为DBUnit属于JUnit一脉,维持数据库稳定只是它的副作用。 它主要作用还是写TestCase。通过它特有的 public static void assertEquals(ITable expected, ITable actual) public static void assertEquals(IDataSet expected, IDataSet actual) 比较数据库中的数据是否符合预设的数据。不过因为Oracle Sequence的一往无前,这个功能我还没有用到(除非每次测试都把Sequence删掉重建并滚动到恰当的位置)
所以,在单元测试中, DBUnit更多的责任也还是负责数据库的稳定,用DatabaseOperation类执行刚才提到的操作,其中还要解决中文问题,详见下文.
另,Oracle的数据库必须写schema. 
|