我正在尝试将DBUnit与普通的JDBC和HSQLDB一起使用,但不能很好地工作--尽管我以前将DBUnit与Hibernate一起使用过,并取得了很大的成功。代码如下:
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)
如果我删除databaseTester.onSetup()行,我将得到一个SQLException:
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?的身份发布了一个后续问题
发布于 2009-10-07 11:54:28
dbUnit不创建表。使用XML文件中给出的有限信息,它也不能。我相信Hibernate可以创建表格。
这是我不再使用内存中的数据库,转而让DBA为每个开发人员提供自己的数据库的原因之一。然后,每个开发人员使用相同的脚本使数据库保持最新,这些脚本稍后会在现场运行。这增加了很小的开销(所有开发人员都需要保持数据库更新),但这意味着您不需要为每次运行构建数据库,并且您可以确保在实时测试工作中运行查询。
第二个原因是速度。我发现创建内存中的数据库比简单地连接到现有的数据库需要更长的时间。
第三个原因是拆卸是非破坏性的(启动会擦除数据库)。这意味着我可以在数据库上运行测试下的SQL,以帮助找出测试失败的原因。
更新:20171115
从那以后,我转而使用JUnit rules that start up a real instance of the database server和FlywayDB之类的东西来构建数据库(并使用与测试中相同的脚本,使用负责构建数据库的应用程序)。它比使用预先构建的数据库要慢得多。但是,使用定义良好的微服务(从而减少需要测试的功能),并且非常严格地限制哪些测试获取数据库,您可以迁移此类问题,并获得始终与实时数据库匹配的本地数据库的好处。
这确实意味着测试拆卸总是破坏性的,但一个合适的断点可以解决这一问题。
发布于 2016-05-03 19:30:27
...several几年后,现在我们有了更好的选择
Spring Boot/ Spring JDBC可以用普通的JDBC初始化数据库。
Spring JDBC有一个DataSource初始化器特性。Spring Boot在默认情况下启用它,并从标准位置
schema.sql
和data.sql
(在类路径的根目录中)加载SQL。此外,Spring Boot将加载schema-${platform}.sql
和data-${platform}.sql
文件(如果存在),其中platform是spring.datasource.platform
的值,例如,您可以选择将其设置为数据库的供应商名称(hsqldb、h2、oracle、mysql、postgresql等)。
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
发布于 2010-09-20 23:04:37
如果您确实像建议的here那样预先创建表,但仍然获得一个NoSuchTableException,那么模式就有问题。在您现在变得疯狂,以各种奇怪而奇妙的方式摆弄它之前,尝试在创建IDatabaseConnection
时将模式参数设置为公共,如下所示:
IDatabaseConnection databaseConnection = new HsqldbConnection(sqlConnection, "PUBLIC");
我花了一些时间使用调试器遍历DbUnit代码,但这似乎可以解决这个问题。
https://stackoverflow.com/questions/1530951
复制相似问题