最近使用dbunit-2.4.8 + Unitils 3.3做DAO层数据库测试的时候
出现如下错误:
org.unitils.core.UnitilsException: Error inserting test data from DbUnit dataset for method public void org.zfanxu.test.UserDaoTestWithUnitils.testGetUserById()
at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:156)
at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:557)
at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273)
at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:151)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:61)
at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:44)
at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:62)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:68)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.unitils.core.UnitilsException: Error while executing DataSetLoadStrategy
at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:46)
at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:230)
at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:153)
... 18 more
Caused by: org.dbunit.dataset.NoSuchColumnException: user.ID - (Non-uppercase input column: id) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
at org.dbunit.dataset.AbstractTableMetaData.getColumnIndex(AbstractTableMetaData.java:117)
at org.dbunit.operation.AbstractOperation.getOperationMetaData(AbstractOperation.java:89)
at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:140)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45)
at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44)
... 20 more
于是在网上google下得知是dbunit的一个bug:http://stackoverflow.com/questions/2210429/dbunit-confusion-over-case-sensitivity-on-table-column-names
google上也基本没有可行的解决方案!
后来我通过修改dbunit的源代码得以解决,错误的原因是unitils默认使用的是“DefaultMetadataHandler.java”这个类去加载数据库信息,从而得不到数据库schema的值
DefaultMetadataHandler.java
boolean areEqual =
areEqualIgnoreNull(catalog, catalogName, caseSensitive) &&
areEqualIgnoreNull(schema, schemaName, caseSensitive) &&
areEqualIgnoreNull(table, tableName, caseSensitive) &&
areEqualIgnoreNull(column, columnName, caseSensitive);
这个时候的schemaName是空的,但是传进来的schema是有值的,从而报错!
所以解决方法如下:
方法1. 修改DefaultMetadataHandler.java文件将上述代码换成如下代码
boolean areEqual =
areEqualIgnoreNull(table, tableName, caseSensitive) &&
areEqualIgnoreNull(column, columnName, caseSensitive);
对,我把catalog和schema的比较都删掉了!
方法2: 因为我使用的是mysql数据库,我直接把dbunit中的类"MySqlMetadataHandler"覆盖掉原来的DefaultMetadataHandler.java文件,同样能解决问题
最后,也来个抛砖引玉,如果有人有更好的解决方法或是可以不通过修改源代码解决的,可以回复我! :-D
分享到:
相关推荐
3. 填充数据库:在测试前使用DbUnit的`IDatabaseConnection`接口和`DataSetLoader`加载数据集到数据库。 4. 执行测试:运行测试代码,这将与数据库交互并执行相关操作。 5. 验证结果:在测试结束后,使用DbUnit的`...
1. 数据集(Dataset):DBUnit的核心是数据集,它可以是XML、CSV或者Excel格式的文件,用来表示数据库中的表和行。例如,测试前,你可以用数据集填充数据库,测试后,再恢复到初始状态。 2. 数据操作:DBUnit提供了...
使用DBUnit时,开发者通常会定义数据集(通常在`dataset.xml`文件中),然后在测试类中引用这些数据集。DBUnit通过JUnit注解(如`@Before`和`@After`)来触发数据的导入和导出。 例如,以下是一个简单的DBUnit测试...
import org.dbunit.dataset.xml.FlatXmlDataSet; import org.junit.*; import javax.sql.DataSource; public class DBUnitTest { private IDatabaseConnection connection; private IDataSet expectedDataSet; ...
在测试方法中,可以调用`dbunit`的方法来执行特定的数据库操作,如导入数据、查询、更新等,并使用`Junit`的断言来验证结果是否符合预期。 例如,以下是一个简单的`Junit + dbunit`测试示例: ```java import org....
DbUnit允许用户导入和导出数据库数据到XML或CSV格式,通过`DataSet`的概念,可以在测试前后加载特定的数据状态。这样,即使测试对数据库进行了修改,也可以在测试结束后恢复原始状态。此外,DbUnit还支持各种操作,...
你可以为这个方法编写一个测试,使用DbUnit来控制测试数据。在测试开始前,DbUnit会清空指定表(在这个例子中可能是`student`表)的数据,并根据预先定义的XML数据集填充测试数据。测试结束后,DbUnit会将数据库状态...
3. **数据填充**:使用 `Dataset` 对象,DbUnit 可以将预定义的数据填充到数据库中,以模拟各种场景。 4. **断言比较**:DbUnit 提供了断言方法,用于比较数据库的实际状态与期望的状态是否一致,有助于确保测试的...
API 文档(http://www.dbunit.org/apidocs/index.html)是 DBUnit 使用的关键资源,其中详细列出了所有类、接口和方法,包括: - `IDatabaseConnection` 接口:表示与数据库的连接,提供创建 Dataset 和执行 SQL ...
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask" classpathref="classpath"/> <!-- 配置数据库连接信息 --> <property name="jdbc.url" value="jdbc:mysql://localhost:3306/testdb"/> ...
5. 断言:展示如何使用 DBUnit 提供的断言方法来验证测试结果。 6. 自定义配置:介绍如何通过 `DatabaseConfig` 修改 DBUnit 的默认行为。 7. 处理复杂数据类型:说明如何处理 BLOB、CLOB 和自定义数据类型。 8. ...
DBUnit 提供了 `IDataFormatter` 接口,可以定制数据的导入导出格式,例如使用 `FlatXMLDataSet` 或 `XMLDataSet` 来处理 XML 文件。 2. **数据恢复**: 数据恢复则涉及将备份数据重新加载到数据库中。在 DBUnit ...
1. 数据集(Dataset):数据集是 DBUnit 的核心,它定义了数据库的预期状态。数据集可以是 XML、CSV 或 Excel 文件,也可以是内存中的对象。数据集包含了插入数据库的行和列,用于初始化或清理测试环境。 2. 模式...
import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.operation.DatabaseOperation; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org....
DBUnit提供了`TRUNCATE_TABLE`方法来清空表,然后使用预定义的dataset填充数据。例如,`init_hibernateDao.xml`文件可能包含了测试所需的初始数据模式。 5. **编写测试方法**:最后,编写具体的测试用例,这些方法...
6. **执行测试**:在测试方法中,使用 `DatabaseTester` 或 `DBUnitHelper` 类来运行 DBUnit 的操作,如 `assertTableCounts()` 或 `assertDataEquals()`,来验证数据库状态。 7. **异常处理**:在测试过程中,如果...
4. **在测试方法中使用Dbunit** 在测试方法的`@Before`注解(或JUnit的`@BeforeClass`)中,我们可以使用`@DatabaseSetup`注解加载测试数据集到数据库。在`@After`注解(或`@AfterClass`)中,使用`@...
DbUnit 是一个针对数据库驱动项目的JUnit...在实际项目中,结合使用DbUnit和其他单元测试框架(如JUnit或TestNG),可以形成强大的测试解决方案,确保整个应用程序的质量,特别是在金融等对数据精确度要求极高的领域。
在上面的代码中,我们使用 `@Configuration` 注解来配置 DBUnit,我们定义了一个名为 `databaseConfig` 的 Bean,其中包含了 DBUnit 的配置信息。同时,我们还定义了一个名为 `dataSource` 的 Bean,其中包含了数据...