我知道这里有关于dbunit的讨论。我已经阅读了大多数文章,但似乎无法找到解决问题的方法。
我已经设置了hibernate and spring。我正在执行TDD,因此在编写代码之前,我必须连接一个适当的DAO测试框架。Dbunit浮现在脑海,我必须进行设置。这是ma testdataset.xml
<?xml version='1.0' encoding='UTF-8'?> <dataset> <table name="status"> <column>statusId</column> <column>status</column> <row> <value>0</value> <value>Available</value> </row> </table> <table name="user"> <column>userId</column> <column>firstName</column> <column>lastName</column> <column>username</column> <column>password</column> <column>email</column> <row> <value>0</value> <value>system</value> <value>admin</value> <value>admin</value> <value>admin</value> <value>admin@ccbs.com</value> </row> </table> <table name="reservation"> <column>reservationId</column> <column>userId</column> <column>reservationDate</column> <column>startDate</column> <column>endDate</column> <column>statusId</column> <row> <value>0</value> <value>0</value> <value>2011-02-20 12:46:00.0</value> <value>2011-03-01 12:00:00.0</value> <value>2011-04-01 12:00:00.0</value> <value>0</value> </row> </table> </dataset>
在我尝试使用加载数据集的基类连接一些代码之前,一切似乎都很好。这是我的代码:
@Transactional @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:test-applicationContext.xml" }) @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) public class BaseContextSensitiveTest { @BeforeClass public static void setUpDatabase() throws Exception { URL file = getInitalDatasetURL(); testDataset = createDataset(file); } @Before public void init() throws Exception { log.info("Initializing Data Set"); connection = createDBUnitConnection(); DatabaseOperation.CLEAN_INSERT.execute(connection, testDataset); } private static URL getInitalDatasetURL() throws FileNotFoundException { URL file = ClassLoader.getSystemResource(TEST_DATASET_LOCATION); if (file == null) { throw new FileNotFoundException("Unable to find '" + TEST_DATASET_LOCATION + "' in the classpath"); } return file; } private static IDataSet createDataset(URL file) throws IOException, DataSetException { return new XmlDataSet(file.openStream()); } private IDatabaseConnection createDBUnitConnection() throws DatabaseUnitException, SQLException { Connection connection = getConnection(); IDatabaseConnection dbUnitConn = new DatabaseConnection(connection); // use the hsql datatypefactory so that boolean properties work // correctly DatabaseConfig config = dbUnitConn.getConfig(); config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory()); return dbUnitConn; }
一旦命中,DatabaseOperation.CLEAN_INSERT.execute(connection, testDataset);它将引发以下异常:
org.dbunit.dataset.NoSuchTableException: Did not find table 'USER' in schema 'null' at org.dbunit.database.DatabaseTableMetaData.<init>(DatabaseTableMetaData.java:142) at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:290) at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109) at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79) at com.cottage.test.BaseContextSensitiveTest.init(BaseContextSensitiveTest.java:64)
我已经准备好了所有的hibernate映射文件,并且数据库已经设置为没有数据。有趣的事情(或令人讨厌的事情,取决于你的查看方式)是,如果我更改数据集中表的顺序,则missingtableexception会抱怨另一个表…用户,保留或状态。
关于我可能在做错的任何建议吗?
我也遇到了同样的错误,上面接受的修复方法没有解决我的问题。但是我能够找到解决方案。
我的设置包括DBUnit(2.4),作为我的JPA提供者的EclipseLink(2.1)和作为我的后端数据库的Postgres。另外,在我的场景中,我没有为每次测试运行删除和重新创建表。我的测试数据已经存在。我知道这是错误的做法,但更多的是测试/原型制作场景。下面的代码说明了用于解决我的问题的DBUnit配置。
54 // ctx represents a spring context 55 DataSource ds = (DataSource)ctx.getBean("myDatasourceBean"); 56 Connection conn = DataSourceUtils.getConnection(ds); 57 IDatabaseConnection dbUnitConn = new DatabaseConnection(conn, "public"); 58 DatabaseConfig dbCfg = dbUnitConn.getConfig(); 59 dbCfg.setFeature(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, Boolean.TRUE); 60 IDataSet dataSet = new FlatXmlDataSet(ClassLoader.getSYstemResourceAsStream("mydbunitdata.xml")); 61 DatabaseOperation.REFRESH.execute(dbUnitConn, dataSet);
上面的代码中的两件事解决了我的问题。首先,我需要定义DBUnit应该使用的架构。这是在上面的第57行上完成的。设置新的DatabaseConnection时,如果schema(“ public”)不为null,则应将其传递。
其次,我需要DBUnit对数据库表名称区分大小写。在我的DBUnit xml文件(“ mydbunitdata.xml”)中,表名都是小写的,就像它们在数据库中一样。但是,如果不告诉DBUnit使用区分大小写的表名,它将查找Postgres不喜欢的大写表名。因此,我需要在第59行完成的DBUnit中设置区分大小写的功能。
DBUnit不会为你创建数据库表,因为它从数据集xml中获得的信息有限,无法创建所需的数据库模式。
当与hibernate一起使用时,它将为每个pojo(你试图映射到内存中的测试数据库表)都需要正确的hbm映射文件,该文件最终将在测试中使用。没有映射文件,你将获得org.dbunit.dataset.NoSuchTableException: Did not find table 'xxx' in schema 'yyy'。
org.dbunit.dataset.NoSuchTableException: Did not find table 'xxx' in schema 'yyy'
另外,需要有效的hibernate.cfg.xml,并使用所有的hibernate映射文件正确配置。
hibernate.cfg.xml
你可以通过hibernate.hbm2ddl.auto=create-drop在属性文件中设置此属性来委派数据库创建以hibernate。
hibernate.hbm2ddl.auto=create-drop
该错误消息有点误导。应该可能包含更多信息,以了解丢失的hibernate映射文件的影响-但这是关于DBunit Wiki的讨论。