1

我正在尝试通过填充具有TIMESTAMP(6) WITH TIME ZONE如下类型列的表来设置数据库单元测试的数据:

<timetable START_TIME="2015-03-01 10.00.00.000000000" END_TIME="2015-03-02 10.00.00.000000000"/>

但是当我运行测试时,我不断收到以下异常:

org.dbunit.dataset.NoSuchColumnException: TIMETABLE.START_TIME -  (Non-uppercase input column: START_TIME) 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:143)
    at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
    at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:194)
    at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:66)
    at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:185)
    at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:249)

我为时间戳字段尝试了不同的格式,包括添加时区后缀 +XX:XX2015-03-01 10.00.00.000000000 +00.00无济于事。我还尝试使用 VM 参数运行测试,-Duser.timezone=UTC但这也无济于事。

有谁知道如何做到这一点?

编辑 1

我在控制台中注意到以下警告:

2016-05-31 14:54:23 WARN  SQLHelper:429 - TIMETABLE.START_TIME data type (-101, 'TIMESTAMP(6) WITH TIME ZONE') not recognized and will be ignored. See FAQ for more information.
2016-05-31 14:54:23 WARN  SQLHelper:429 - TIMETABLE.END_TIME data type (-101, 'TIMESTAMP(6) WITH TIME ZONE') not recognized and will be ignored. See FAQ for more information.

所以看起来 Dbunit 不支持TIMESTAMP WITH TIME ZONE数据类型并忽略它,因此出现NoSuchColumnException异常

编辑 2

实际上 dbunit 已经TIMESTAMP通过类支持数据类型OracleDataTypeFactory。配置将如下所示:

<bean id="oracleDataTypeFactory" class="org.dbunit.ext.oracle.OracleDataTypeFactory"/>

<bean id="dbUnitDatabaseConfig" class="com.github.springtestdbunit.bean.DatabaseConfigBean">
        <property name="datatypeFactory" ref="oracleDataTypeFactory" />
</bean>

不幸的是,在这些配置更改之后,数据类型问题仍然存在,因为 dbunit DatabaseConfig.datatypeFactory 属性被 DbUnitTestExecutionListener 重新设置为DefaultDataTypeFactory不支持 TIMESTAMP 数据类型的默认值

4

1 回答 1

0

我设法TIMESTAMP通过删除 Spring-dbunit 特定的注释(@TestExecutionListeners@DbUnitConfiguration)来加载数据。我还是得用@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)。然后,我使用“旧”Dbunit 方法来设置和拆卸数据并检查数据预期。这不像 Spring-dbunit annotations和那样简洁@DatabaseSetup,但它确实有效(参见下面的代码片段)。我还在我的测试上下文中保留了 OracleDataTypeFactory;这对于 Dbunit 识别 TIMESTAMP 数据类型至关重要。@DatabaseTearDown@ExpectedDatabase

我认为我面临的问题可能是 spring-dbunit 测试执行侦听器中的错误表现。我特别怀疑DbUnitTestExecutionListener

设置:

@Before
    public void setUp() throws SQLException, IOException, DataSetException, DatabaseUnitException {    
        Resource resource = new ClassPathResource("path/to/data_setup.xml");
        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
        builder.setColumnSensing(true);
        FlatXmlDataSet dataSetup = builder.build(resource.getInputStream());
        DatabaseOperation.CLEAN_INSERT.execute(dbUnitDatabaseConnection, dataSetup);    
    }

拆除:

@After
    public void tearDown() throws SQLException, IOException, DataSetException, DatabaseUnitException {
        Resource resource = new ClassPathResource("path/to/data_teardown.xml");
        FlatXmlDataSet dataTearDown = new FlatXmlDataSetBuilder().build(resource.getInputStream());
        DatabaseOperation.DELETE_ALL.execute(dbUnitDatabaseConnection, dataTearDown);
    }

期望(在测试方法内):

QueryDataSet actualDataSet = new QueryDataSet(dbUnitDatabaseConnection);
actualDataSet.addTable("YOUR_TABLE", "<YOUR_SQL_QUERY>");
FlatXmlDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(new ClassPathResource("path/to/data_expectation.xml").getInputStream());
Assertion.assertEquals(expectedDataSet, actualDataSet);
于 2016-06-01T10:27:49.860 回答