Saturday, September 27, 2014

DbUnit FlatXmlDataSet - How to Ignore DTD

I started out trying to use DbUnit FlatXmlDataSet without a DTD, but DbUnit threw an exception, so I generated a DTD from my schema by using FlatDtdDataSet, and put the path to the DTD at the DOCTYPE declaration, and everything worked fine.

However, I was worried that the tests won't be portable, since there's no telling how the compiled integration test code was going to be packaged and deployed. Of course, the proper practice in Java for accessing a file is through the classpath, via class.getResourceAsStream. I was able to do that for the dataset XML file, but DbUnit was still looking for the DTD at the relative path defined at the DOCTYPE declaration.  I couldn't figure out how to get the DTD from the classpath.

Eventually I just decided to ignore the DTD. I did this via the FlatXmlDataSetBuilder.setDtdMetadata() method. See my getDataSet() method implementation below:

protected IDataSet getDataSet() throws Exception {
    FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
    builder.setDtdMetadata(false);
    return builder.build( getClass().getResourceAsStream("SectionDaoTest.xml") );
}

The problem with ignoring the DTD is that if the first row of a table has one or more null values, DbUnit might throw a NoSuchColumnException, since without the DTD, DbUnit uses the columns defined in the first row to define the table. The workarounds are either to make sure that their are no nulls in the first row of each table, or to use ReplacementDataSet

No comments:

Post a Comment