为IDatabaseConnection(HSQLDB)设置数据库配置属性时出错

时间:2017-01-04 19:07:05

标签: postgresql unit-testing integration-testing hsqldb dbunit

我在下面包含了完全可测试的代码,当提供包含空字段的数据集xml时,会生成以下错误。样本dataset.xml也位于下方。

  

java.lang.IllegalArgumentException:table.column = places.CITY value is   空但必须包含值(要禁用此功能检查,请设置   DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS为true)

线程here类似但不同,因为它使用多个dbTester.getConnection()而我的代码只使用一个,但却有相同的错误。主要问题涉及这一行databaseConfig.setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, Boolean.TRUE);  它似乎完全被忽略了。我已尝试将init代码放在@Test方法中,但错误仍然存​​在。

dataset.xml

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <places address="123 Up Street" city="Chicago" id="001"/>
  <places address="456 Down Street" city="" id="002"/>
  <places address="789 Right Street" city="Boston" id="003"/>
</dataset>

代码:

import org.dbunit.IDatabaseTester;
import org.dbunit.JdbcDatabaseTester;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class DBConnectionIT {
    IDatabaseTester databaseTester = null;
    IDatabaseConnection iConn = null;
    Connection connection = null;

    @Before
    public void init() throws Exception {
        databaseTester = new JdbcDatabaseTester(org.hsqldb.jdbcDriver.class.getName(), "jdbc:hsqldb:mem:testdb;sql.syntax_pgs=true", "sa", "");
        iConn = databaseTester.getConnection();
        DatabaseConfig databaseConfig = iConn.getConfig();
        databaseConfig.setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, Boolean.TRUE);
        connection = iConn.getConnection();
        createTable(connection);
        IDataSet dataSet = new FlatXmlDataSetBuilder().build(new File("dataset.xml"));
        databaseTester.setDataSet(dataSet);
        databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT);
        databaseTester.setTearDownOperation(DatabaseOperation.DELETE_ALL);
        databaseTester.onSetup();
    }

    @Test
    public void testDBUnit() {
        try {
            PreparedStatement pst = connection.prepareStatement("select * from places");
            ResultSet rs = pst.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void createTable(Connection conn) throws Exception {
        PreparedStatement pp = conn.prepareStatement(
                "CREATE TABLE PLACES" +
                        "(address VARCHAR(255), " +
                        "city TEXT, " +
                        "id VARCHAR(255) NOT NULL primary key)");
        pp.executeUpdate();
        pp.close();
    }
}

编辑(根据CésarRodríguez的回答):

我现在在父类中重构了这个方法:

 protected void setUpDatabaseConfig(DatabaseConfig databaseConfig) {
        databaseConfig.setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, Boolean.TRUE);
    }

并创建了一个子类@Overrides这个方法,但是它说没有使用这个子类。如何在父类中解决此类(DBConnectionOverride)以解决我的问题?

class DBConnectionOverride extends DBConnectionIT {
    @Override
    protected void setUpDatabaseConfig(DatabaseConfig databaseConfig) {
        databaseConfig.setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true);
    }
}

3 个答案:

答案 0 :(得分:2)

我偶然发现了正确答案,至少解决了我的问题。它与databaseTester.onSetup()一直相关,可以简单地用DatabaseOperation.CLEAN_INSERT.execute(iConn, dataSet);替换。免费评论为什么这似乎修复了错误。

答案 1 :(得分:0)

您必须覆盖方法setUpDatabaseConfig(DatabaseConfig config),如下所示:

@Override
protected void setUpDatabaseConfig(DatabaseConfig config) {
    config.setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true); 
}

希望有所帮助

答案 2 :(得分:0)

对我而言,这有效:

IDatabaseConnection dbConn = new DatabaseDataSourceConnection(getDataSource());
dbConn.getConfig().setProperty(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true);
DatabaseOperation.CLEAN_INSERT.execute(dbConn, getiDataSet(loadDBData.source()));