`
zfanxu
  • 浏览: 127269 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

使用Dbunit+Unitils出现 org.dbunit.dataset.NoSuchColumnException 的解决方法

阅读更多

最近使用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

分享到:
评论
5 楼 terrymanu 2013-10-25  
非常感谢楼主抛砖引玉,提供了这个问题的解决方案。
我根据你提供的知识,又仔细看了下源码,找到一个不用修改源码,而是使用扩展的方式修复这个问题。
可以直接覆盖DbUnitModule,重写getDbUnitDatabaseConnection方法,将mysql或者其他数据库需要的MetadataHandler注进去。
我写了一个帖子,详情请见
http://my.oschina.net/u/719192/blog/171387
欢迎交流
4 楼 lfy2008 2013-05-03  
楼主有重新编译的jar包没?发一个 。Unitils3.3的maven地址找不到啊
3 楼 javafansmagic 2012-11-13  
用Unitils 3.3默认依赖的dbunit 2.2.2版本就没有这个问题。
2 楼 zfanxu 2012-07-18  
happyJavaer 写道
求解决方案啊,除了这两种之外楼主想出其他方法了吗?

呵呵,在使用unitils和dbunit整合时,实际使用过程中,并没有想象中的那么方便!
至于这个问题,目前情况下,必须得改源代码实现
1 楼 happyJavaer 2012-07-18  
求解决方案啊,除了这两种之外楼主想出其他方法了吗?

相关推荐

    dbunit-2.2.3-prj.rar_DbUnit 2.2_dbunit_单元测试

    3. 填充数据库:在测试前使用DbUnit的`IDatabaseConnection`接口和`DataSetLoader`加载数据集到数据库。 4. 执行测试:运行测试代码,这将与数据库交互并执行相关操作。 5. 验证结果:在测试结束后,使用DbUnit的`...

    dbunit-2.0-src.zip_dbunit src_dbunit-2.1-src

    1. 数据集(Dataset):DBUnit的核心是数据集,它可以是XML、CSV或者Excel格式的文件,用来表示数据库中的表和行。例如,测试前,你可以用数据集填充数据库,测试后,再恢复到初始状态。 2. 数据操作:DBUnit提供了...

    dbunit-2.1.zip_dbunit docs_zip

    使用DBUnit时,开发者通常会定义数据集(通常在`dataset.xml`文件中),然后在测试类中引用这些数据集。DBUnit通过JUnit注解(如`@Before`和`@After`)来触发数据的导入和导出。 例如,以下是一个简单的DBUnit测试...

    dbunit使用实例

    import org.dbunit.dataset.xml.FlatXmlDataSet; import org.junit.*; import javax.sql.DataSource; public class DBUnitTest { private IDatabaseConnection connection; private IDataSet expectedDataSet; ...

    Junit+dbunit单元测试jar包

    在测试方法中,可以调用`dbunit`的方法来执行特定的数据库操作,如导入数据、查询、更新等,并使用`Junit`的断言来验证结果是否符合预期。 例如,以下是一个简单的`Junit + dbunit`测试示例: ```java import org....

    junit4.10+dbunit2.4.7+httpunit+junitperf的jar包

    DbUnit允许用户导入和导出数据库数据到XML或CSV格式,通过`DataSet`的概念,可以在测试前后加载特定的数据状态。这样,即使测试对数据库进行了修改,也可以在测试结束后恢复原始状态。此外,DbUnit还支持各种操作,...

    使用DbUnit测试数据库.pdf

    你可以为这个方法编写一个测试,使用DbUnit来控制测试数据。在测试开始前,DbUnit会清空指定表(在这个例子中可能是`student`表)的数据,并根据预先定义的XML数据集填充测试数据。测试结束后,DbUnit会将数据库状态...

    dbunit入门实例

    3. **数据填充**:使用 `Dataset` 对象,DbUnit 可以将预定义的数据填充到数据库中,以模拟各种场景。 4. **断言比较**:DbUnit 提供了断言方法,用于比较数据库的实际状态与期望的状态是否一致,有助于确保测试的...

    dbunit-2.4.9 源码

    API 文档(http://www.dbunit.org/apidocs/index.html)是 DBUnit 使用的关键资源,其中详细列出了所有类、接口和方法,包括: - `IDatabaseConnection` 接口:表示与数据库的连接,提供创建 Dataset 和执行 SQL ...

    DBUnit最佳实践之使用ant命令

    <taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask" classpathref="classpath"/> <!-- 配置数据库连接信息 --> <property name="jdbc.url" value="jdbc:mysql://localhost:3306/testdb"/> ...

    dbunit-2.4.7所有jar以及dbunit入门教程

    5. 断言:展示如何使用 DBUnit 提供的断言方法来验证测试结果。 6. 自定义配置:介绍如何通过 `DatabaseConfig` 修改 DBUnit 的默认行为。 7. 处理复杂数据类型:说明如何处理 BLOB、CLOB 和自定义数据类型。 8. ...

    如何使用DBUnit做数据备份恢复

    DBUnit 提供了 `IDataFormatter` 接口,可以定制数据的导入导出格式,例如使用 `FlatXMLDataSet` 或 `XMLDataSet` 来处理 XML 文件。 2. **数据恢复**: 数据恢复则涉及将备份数据重新加载到数据库中。在 DBUnit ...

    dbunit开发文档

    1. 数据集(Dataset):数据集是 DBUnit 的核心,它定义了数据库的预期状态。数据集可以是 XML、CSV 或 Excel 文件,也可以是内存中的对象。数据集包含了插入数据库的行和列,用于初始化或清理测试环境。 2. 模式...

    Spring Boot 与DBunit 配合使用方法

    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测试规范[收集].pdf

    DBUnit提供了`TRUNCATE_TABLE`方法来清空表,然后使用预定义的dataset填充数据。例如,`init_hibernateDao.xml`文件可能包含了测试所需的初始数据模式。 5. **编写测试方法**:最后,编写具体的测试用例,这些方法...

    dbunit测试demo

    6. **执行测试**:在测试方法中,使用 `DatabaseTester` 或 `DBUnitHelper` 类来运行 DBUnit 的操作,如 `assertTableCounts()` 或 `assertDataEquals()`,来验证数据库状态。 7. **异常处理**:在测试过程中,如果...

    主题:在Spring中结合Dbunit对Dao进行集成单元测试

    4. **在测试方法中使用Dbunit** 在测试方法的`@Before`注解(或JUnit的`@BeforeClass`)中,我们可以使用`@DatabaseSetup`注解加载测试数据集到数据库。在`@After`注解(或`@AfterClass`)中,使用`@...

    介绍dbunit的使用和原理,核心组件介绍

    DbUnit 是一个针对数据库驱动项目的JUnit...在实际项目中,结合使用DbUnit和其他单元测试框架(如JUnit或TestNG),可以形成强大的测试解决方案,确保整个应用程序的质量,特别是在金融等对数据精确度要求极高的领域。

    SpringBoot DBUnit 单元测试(小结)

    在上面的代码中,我们使用 `@Configuration` 注解来配置 DBUnit,我们定义了一个名为 `databaseConfig` 的 Bean,其中包含了 DBUnit 的配置信息。同时,我们还定义了一个名为 `dataSource` 的 Bean,其中包含了数据...

Global site tag (gtag.js) - Google Analytics