无法使用dbunit和h2数据库从xml读取数据集

时间:2015-04-28 19:29:07

标签: java unit-testing dbunit

当dbunit尝试从XML文件中读取数据时,我收到NoSuchTableException异常。最初我认为这个问题与HSQLDB有关,因此切换到H2数据库,但问题仍然存在。我是dbunit的新手,无法获得一些关于此的最新文档。在线发现的所有教程都使用了dbunit的旧版本,而且描述性不够。

不确定这里发生了什么。任何人都可以指导我这个程序有什么问题吗?

错误记录

SEVERE: Table 'users' not found in tableMap=org.dbunit.dataset.OrderedTableNameMap[_tableNames=[], _tableMap={}, _caseSensitiveTableNames=false]
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.493 sec <<< FAILURE!
testGetUser(com.istore.dao.UserDaoTest)  Time elapsed: 0.42 sec  <<< ERROR!
org.dbunit.dataset.NoSuchTableException: users
    at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:288)
    at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109)
    at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
    at org.dbunit.AbstractDatabaseTester.executeOperation(AbstractDatabaseTester.java:190)
    at org.dbunit.AbstractDatabaseTester.onSetup(AbstractDatabaseTester.java:103)

的pom.xml

   <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.187</version>
        <scope>runtime</scope>
    </dependency>

的src /测试/资源/ users.xml中

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <users id="1" name="Nital"/>
</dataset>

AbstractUserDaoTest.java

public class AbstractUserDaoTest extends DataSourceBasedDBTestCase {

    private static final String USERS_DATASET = "/users.xml";
    private static final UserDao dao = new UserDao();
    protected static Connection connection;
    protected static HsqldbConnection dbunitConnection;

    @Override
    protected DataSource getDataSource() {
        //create datasource
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:test");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return dataSource;
    }

    @Override
    protected IDataSet getDataSet() throws Exception {
        String fileName = getClass().getResource(USERS_DATASET).getFile();
        System.out.println("fileName = " + fileName);
        FlatXmlDataSet dataset = new FlatXmlDataSetBuilder().build(new FileInputStream(fileName));
        System.out.println("dataset = " + dataset);
        String[] tableNames = dataset.getTableNames();
        for (String t : tableNames) {
            System.out.println("t = " + t);
        }
        return dataset;
    }

    @AfterClass
    public void closeDatabase() throws Exception {
        if (connection != null) {
            connection.close();
            connection = null;
        }
        if (dbunitConnection != null) {
            dbunitConnection.close();
            dbunitConnection = null;
        }
    }
}

UserDaoTest.java

public class UserDaoTest extends AbstractUserDaoTest {
    @Test
    public void testGetUser() {
        String a = "abc";
        assertNotNull(a);
    }
}

UserDao.java

public class UserDao extends BaseDao {

    private static final Logger LOG = Logger.getLogger(UserDao.class);

    public UserDao() {
    }

    public UserDao(DataSource dataSource) throws SQLException {
        super(dataSource);
    }

    public User getUser(String userCd) throws SQLException {
        String sql = "select * from users a where a.user_cd='" + userCd + "' and a.active='Y'";
        System.out.println("sql = " + sql);
        UserQueryExecutor executor = new UserQueryExecutor(dataSource.getConnection(), sql);
        User user = executor.getUser();
        LOG.debug("user = " + user);
        return user;
    }

    //used in dbunit tests
    public boolean createTable() throws SQLException {
        String sql = "CREATE TABLE users (" +
                    "  id  INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1)," +
                    "  name VARCHAR(100) NOT NULL) ";
        System.out.println("sql = " + sql);
        System.out.println("cn = " + dataSource.getConnection());
        UserQueryExecutor queryExecutor = new UserQueryExecutor(dataSource.getConnection(), sql);
        boolean success = queryExecutor.createTable();
        System.out.println("success = " + success);
        return success;
    }

}

BaseDao.java

public class BaseDao {

    private static final Logger LOG = Logger.getLogger(BaseDao.class);

    protected DataSource dataSource;
    //using this field for dbunit tests, otherwise dataSource will be sufficient
    protected Connection connection;

    public BaseDao() {
    }

    public BaseDao(DataSource dataSource) throws SQLException {
        this.dataSource = dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    //used only for dbunit tests
    public void setConnection(Connection connection) {
        this.connection = connection;
    }

}

UserQueryExecutor.java

public final class UserQueryExecutor extends BaseQueryExecutor {

    private static final Logger LOG = Logger.getLogger(UserQueryExecutor.class);

    public UserQueryExecutor(Connection cn, String sql) {
        super(cn, sql);
    }

    public User getUser() {
        Statement stmt = null;
        ResultSet rs = null;
        User user = null;

        LOG.debug(sql);

        try {
            stmt = cn.createStatement();
            rs = stmt.executeQuery(sql);
            while (rs != null && rs.next()) {
                user = new DataPopulator().populateUser(rs);
            }
            LOG.debug("user = " + user);
        } catch (SQLException ex) {
            LOG.error("Exception whiile fetching data for a user.......", ex);
        } finally {
            DbUtils.closeQuietly(cn, stmt, rs);
        }
        return user;
    }

    public boolean createTable() {
        Statement stmt = null;
        ResultSet rs = null;
        boolean tableCreated = false;

        LOG.debug(sql);

        try {
            stmt = cn.createStatement();
            tableCreated = stmt.execute(sql);
            LOG.debug("tableCreated = " + tableCreated);
        } catch (SQLException ex) {
            LOG.error("Exception whiile creating user table.......", ex);
        } finally {
            DbUtils.closeQuietly(cn, stmt, rs);
        }
        return tableCreated;
    }

}

BaseQueryExecutor.java

public class BaseQueryExecutor {

    protected Connection cn;
    protected String sql;

    public BaseQueryExecutor(Connection cn, String sql) {
        this.cn = cn;
        this.sql = sql;
    }

}

1 个答案:

答案 0 :(得分:0)

DBUnit不会自动从XML数据集创建数据库表,因为它没有足够的信息。 除非我弄错了,否则你不能在任何地方调用createTable()的{​​{1}}方法。

因此,您必须在测试之前执行脚本来创建数据库模式(通常可以在setUp方法中执行)。其他SO问题中有更多信息,例如this

希望它有所帮助。