代码之家  ›  专栏  ›  技术社区  ›  neu242

如何在不遇到NoSuchTableException的情况下,使用带有普通JDBC和HSQLDB的DBUnit进行测试?

  •  16
  • neu242  · 技术社区  · 16 年前

    import java.sql.PreparedStatement;
    import org.dbunit.IDatabaseTester;
    import org.dbunit.JdbcDatabaseTester;
    import org.dbunit.dataset.IDataSet;
    import org.dbunit.dataset.xml.XmlDataSet;
    import org.junit.Test;
    
    public class DummyTest {
    
        @Test
        public void testDBUnit() throws Exception {
            IDatabaseTester databaseTester = new JdbcDatabaseTester("org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem", "sa", "");
            IDataSet dataSet = new XmlDataSet(getClass().getResourceAsStream("dataset.xml"));
            databaseTester.setDataSet(dataSet);
            databaseTester.onSetup();
            PreparedStatement pst = databaseTester.getConnection().getConnection().prepareStatement("select * from mytable");
        }
    }
    

    这就是所讨论的dataset.xml:

    <dataset>
        <table name="mytable">
            <column>itemnumber</column>
            <column>something</column>
            <column>other</column>
            <row>
                <value>1234abcd</value>
                <value>something1</value>
                <value>else1</value>
            </row>
        </table>
    </dataset>
    

    此测试为我提供了一个NoSuchTableException:

    org.dbunit.dataset.NoSuchTableException: mytable
        at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:282)
        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)
        at DummyTest.testDBUnit(DummyTest.java:18)
    

    java.sql.SQLException: Table not found in statement [select * from mytable]
        at org.hsqldb.jdbc.Util.throwError(Unknown Source)
        at org.hsqldb.jdbc.jdbcPreparedStatement.<init>(Unknown Source)
        at org.hsqldb.jdbc.jdbcConnection.prepareStatement(Unknown Source)
        at DummyTest.testDBUnit(DummyTest.java:19)
    

    数据集本身正在工作,因为我可以像它应该的那样访问它:

    ITable table = dataSet.getTable("mytable");
    String firstCol = table.getTableMetaData().getColumns()[0];
    String tName = table.getTableMetaData().getTableName();
    

    编辑 :正如@mlk指出的,DBUnit不创建表。如果在添加数据集之前插入以下内容,则一切都会顺利进行:

    PreparedStatement pp = databaseTester.getConnection().getConnection().prepareStatement(
         "create table mytable ( itemnumber varchar(255) NOT NULL primary key, "
       + " something varchar(255), other varchar(255) )");
    pp.executeUpdate();
    

    Is there any way for DBUnit to automatically create tables from a dataset or dtd?

    3 回复  |  直到 9 年前
        1
  •  19
  •   Michael Lloyd Lee mlk    8 年前

    dbUnit不创建表。在XML文件中给出的有限信息下,它也无法实现。我相信Hibernate可以创建表。

    第二个原因是速度。我发现创建内存中的数据库比简单地连接到现有数据库花费的时间要长得多。

    第三个原因是拆除没有破坏性(启动会擦除数据库)。这意味着我可以在数据库上运行被测SQL,以帮助找出测试失败的原因。


    更新 : 20171115

    JUnit rules that start up a real instance of the database server 什么的 FlywayDB 构建数据库(在live中使用与在test中相同的脚本,由应用程序负责构建数据库)。它比使用预构建的数据库要慢得多。但是,使用定义良好的微服务(从而减少了需要测试的功能)和非常严格的数据库测试,您可以迁移这些问题,并获得始终与实时数据库匹配的本地数据库的好处。

    这确实意味着测试破坏总是具有破坏性的,但一个位置合适的断点可以解决这一问题。

        2
  •  4
  •   Asa    9 年前

    …几年后,现在我们有了更好的选择

    SpringBoot/SpringJDBC可以使用普通JDBC初始化数据库。

    SpringJDBC具有数据源初始值设定项功能。弹簧启动启用 默认情况下,它从标准位置加载SQL schema.sql data.sql (在类路径的根目录中)。此外,弹簧靴将 加载 schema-${platform}.sql data-${platform}.sql 当前),其中平台是 spring.datasource.platform , (hsqldb、h2、oracle、mysql、postgresql等)。

    https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html

        3
  •  0
  •   Community Mohan Dere    9 年前

    here 并且仍然会得到一个NoSuchTableException,那么架构就有问题了。在你发疯之前,试着将schema参数设置为 公开的 当您创建 IDatabaseConnection ,例如:

    IDatabaseConnection databaseConnection = new HsqldbConnection(sqlConnection, "PUBLIC");
    

    推荐文章