注: 本篇的测试使用的数据库为Oracle, 其它数据库的情况可能会有所不同。
ReplacementDataSet继承AbstractDataSet, 而AbstractDataSet实现了IDataSet接口。
因此Dbunit中任何以IDataSet为参数对象类型的方法都可以使用ReplacementDataSet.
下面是这篇教程的应用场景:
Channel类:
@Entity
@Table(name="t_channel")
@SequenceGenerator(name="TestSEQ",sequenceName="test_seq",allocationSize=1,initialValue=100)
public class Channel {
/**
* 栏目的主键
*/
private int id;
/**
* 栏目的名称
*/
private String name;
/**
* 父类栏目
*/
private Channel parent;
@ManyToOne
@JoinColumn(name="pid")
public Channel getParent() {
return parent;
}
public void setParent(Channel parent) {
this.parent = parent;
}
...
}
这里的Channel是一个树形结构,每一个Channel有它的父级和子级。
在数据库中, 用一个pid外键关联到自身的id。
<t_channel id="0" name="网站系统栏目" pid="null"/>
<t_channel id="1" name="用户管理模块" pid="0"/>
<t_channel id="2" name="用户管理1" pid="1"/>
<t_channel id="3" name="用户管理2" pid="1"/>
<t_channel id="4" name="用户管理3" pid="1"/>
<t_channel id="5" name="用户管理4" pid="1"/>
测试数据结构如上所示:
------------------------------------
网站系统栏目
-用户管理模块
-用户管理1
-用户管理2
-用户管理3
-用户管理4
-------------------------------------
网站的根栏目是 网站系统栏目, id=0, pid=null
然后是 用户管理模块 id=1, pid=0,
接下来是用户管理1,2,3,4 id为别为2,3,4,5 , pid都是1, 也就是用户管理模块的子模块。
测试:
1.
IDataSet ds=createDataSet("topic"); //createDataSet(String filename)通过文件输入流,返回一个测试数据对象。详情见入门教程
DatabaseOperation.CLEAN_INSERT.execute(dbunitCon,ds);
上面的代码会情况数据库,并插入xml文件中的测试数据。
但是运行之后会意外的发现错误信息:
org.dbunit.dataset.datatype.TypeCastException: Error casting value for table 't_channel' and column 'PID'
at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:193)
at com.lj.core.dao.TestChannelDao.setUp(TestChannelDao.java:63)
Caused by: org.dbunit.dataset.datatype.TypeCastException: Unable to typecast value <null> of type <java.lang.String> to DECIMAL
Caused by: java.lang.NumberFormatException
at java.math.BigDecimal.<init>(BigDecimal.java:368)
at java.math.BigDecimal.<init>(BigDecimal.java:647)
at org.dbunit.dataset.datatype.NumberDataType.typeCast(NumberDataType.java:79)
... 37 more
也就是说,pid=null这里是不能被插入数据库的。
这时我们会首先把它去掉,看看能不能解决问题。
2. 于是我们改成<t_channel id="0" name="网站系统栏目" />
再次运行测试。
结果发现数据被导入数据库, 只不过pid那一列全部没有任何数值。
看来测试数据的pid是不能去掉的。
3. 要解决这个问题, 就必须使用ReplacementDataSet,将xml测试文件中的字符串的
"null"转换成实际的
null。
代码如下:
IDataSet ds=createDataSet("topic");
ReplacementDataSet rds=new ReplacementDataSet(ds);
rds.addReplacementObject("null", null); //将“null”转换成null.
DatabaseOperation.CLEAN_INSERT.execute(dbunitCon,rds);
此时将网站系统栏目加入 pid="null",
再次运行测试代码,就可以看到数据被正常加入了进去。
网站系统栏目那里的pid是没有值的,就达到我们的需求了。