日期:2014-05-16  浏览次数:20559 次

HSQL 内存数据库在unit test 中的使用

如果我们项目采用 Hibernate ?访问DB2/Oracle 的应用需要做unit test。 应该怎么做呢?

一种 ?是 连真实的db2 的数据库, 每一个需要数据库访问的 ?unit ?test 放到 transaction 中 , 在unit test After 方法中 ?rollback ?所做的 transaction, ?保证数据库clean。

?

另外一种是连H2 ?或者 HSql 之类的内存数据库, ?每一个unit test 都是干净的数据库。 ?这两种方法应该将各有利弊, ?采用相同类型的数据库, 如果 unit test 失败 或者 unit test 之间可能会造成 干扰, ?而内存数据库呢毕竟是不同类型。 涉及到DAO 中要采用 特定数据库的特性就不行了。 ? 比如现有项目是访问 DB2数据库, 在插入或者修改业务数据表时 会通过触发器 在业务表的audit 表中增加audit 数据。 ?这个用内存数据库就得不到相同的结果。 ?

?

各有利弊也得选啊, ?客户选择了用HSQL 来做 db unit test。 ?跟 HSQL 做 unit test 的最佳拍档 是 dbunit。 ?我们可以准备好 ?DDL 来创建表结构。 数据呢, 通过把DB2中的 数据导出到 xml 中 ?, ?dbunit 可以将一个xml 文件看成一个dataset。 ? 这点跟 dotNet 中的 ADO.NET 比较相似, 一个dataset 中 也可以指定多个表的数据。但是这有个缺点, 如果数据量大了, 性能就很差, 原因当然是xml document 的解析效率太差。 我现在是采用了自己生成insert sql 语句。 然后利用 HSql 的?org.hsqldb.cmdline.SqlFile ?可以很方便的执行一个sql 文件。 采用这种方式, 基本上可以将测试数据库里面的所有测试数据倒出来 几千 上万条数据, 100 多张表 也就 10几秒钟 搞定到内存。

?

?

在使用hsql jar 包的时候碰到一个问题, 主键用 identity 类型 的时候 只有 1.8 版本的 不支持 Hibernate ?的 getGeneratedkey, 会抛出一个错误, 换成 2.2.6 之后 OK。

?

?

目前做了两个 utiltiy 类 : 一个是生成表的 ddl, ?一个是 生成 指定表的 insert sql。 ddl 可以所有表都放到一个文件, 而数据可以做成 一张表一个文件, 并且在具体的test 之间有开发人员之间加。 ?ddl 则放到 test 基类每次加载。?