Postgresql DBUnit&;Postgres UUID主键
我试图使用DBUnit来运行集成测试,但是我发现自己无法插入主键列,这显然不适用于稍后在文件中引用主键的外键 例如,我有以下DDL:Postgresql DBUnit&;Postgres UUID主键,postgresql,dbunit,spring-test-dbunit,Postgresql,Dbunit,Spring Test Dbunit,我试图使用DBUnit来运行集成测试,但是我发现自己无法插入主键列,这显然不适用于稍后在文件中引用主键的外键 例如,我有以下DDL: CREATE TABLE attributes( attribute_id UUID NOT NULL DEFAULT uuid_generate_v4(), attribute VARCHAR(64) NOT NULL, description TEXT NOT NULL, PRIMARY KEY(attribute_id) );
CREATE TABLE attributes(
attribute_id UUID NOT NULL DEFAULT uuid_generate_v4(),
attribute VARCHAR(64) NOT NULL,
description TEXT NOT NULL,
PRIMARY KEY(attribute_id)
);
DBUnit设置XML如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<dataset>
<attributes attribute_id="233bc966-4fcd-4b46-88e6-3e07090f322d" attribute="Empathy" description="Empathy Description" />
</dataset>
以下是正在运行的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@DbUnitConfiguration(dataSetLoader = TestConfiguration.FlatXmlDataLoaderProxy.class)
@ContextConfiguration(classes = {ApplicationConfiguration.class, TestConfiguration.class})
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class
})
public class ApplicationAssessmentJobTest {
@Autowired
private ApplicationAssessmentJob applicationAssessmentJob;
@Test
@DatabaseSetup("/dbunit/ApplicationAssessmentJobTestSetup.xml")
@DatabaseTearDown("dbunit/ApplicationAssessmentJobTestTearDown.xml")
public void testJob() {
ApplicationAssessmentJobModel model = new ApplicationAssessmentJobModel();
model.setApplicationId(UUID.fromString("41fa1d51-c1ee-482b-80a7-a6eefda64436"));
applicationAssessmentJob.receiveMessage(model);
}
}
显示的此错误似乎与根本问题没有直接关系。如果我从XML中删除
属性\u id
列,则会插入记录。在与DBUnit/Spring Test DBUnit斗争了一天的大部分时间后,我决定放弃该库并使用自己的库,因为DBUnit似乎只是一种痛苦
我能够在不到30分钟的时间内用大约40个SLoC编写一个安装/拆卸程序。它使用简单的SQL,这在哲学上更符合我对Hibernate的选择。当然不太理想,但15分钟的搜索并没有找到任何东西来处理在安装和拆卸时运行SQL的简单用例。值得注意的是,ApplicationContext
提供的java.sql.DataSource
Bean上的一个需求
DbInitTestExecutionListener.java
DatabaseTearDown.java
DatabaseSetup.java
使用最小的测试配置:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {ApplicationConfiguration.class})
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbInitTestExecutionListener.class
})
public class TestClass {
@Test
@DatabaseSetup("/dbinit/TestSetup.sql")
@DatabaseTearDown("/dbinit/TestTearDown.sql")
public void testJob() {
// TODO: Add test code here
}
}
此错误消息
org.dbunit.dataset.NoSuchColumnException: attributes.ATTRIBUTE_ID ...
表明dbunit正在查找名为属性\u ID
的列。CREATE TABLE语句创建一个名为attribute\u id
的列
如果DbOnUnt使用分隔标识符,PostgreSQL将考虑<代码>属性属性“< /代码>和<代码>”属性“ID /代码>”作为两个不同的标识符。(在您的情况下,两个不同的列)如果dBUnt不使用分隔标识符,PostgreSQL将折叠为小写,它将考虑<代码> AtditTyId < /C> >和<代码> AtditTyId < /C> >是相同的标识符-<代码> AtditTyId < /C> > SQL标准要求将普通标识符折叠为大写。PostgreSQL在这里的行为并不标准,但不太可能改变
看起来dbunit可能会自行折叠为大写(遵循SQL标准)。如果是这种情况,您可能可以将dbunit配置为使用区分大小写的标识符。(我不知道该怎么做。)我也遇到了同样的问题,我终于找到了解决办法。 正如文档中提到的,您需要覆盖默认的dbunit DatabaseConfig,以便为PostgreSQL设置特定于IDataTypeFactory的值 以下是我的测试配置:
@Autowired
private DataSource dataSource;
@Bean
public DatabaseConfigBean databaseConfigBean() {
DatabaseConfigBean databaseConfigBean = new DatabaseConfigBean();
databaseConfigBean.setDatatypeFactory(new PostgresqlDataTypeFactory());
return databaseConfigBean;
}
@Bean(name = "dbUnitDatabaseConnection")
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() throws SQLException, DatabaseUnitException, IOException {
DatabaseDataSourceConnectionFactoryBean databaseDataSourceConnectionFactoryBean = new DatabaseDataSourceConnectionFactoryBean();
databaseDataSourceConnectionFactoryBean.setDatabaseConfig(databaseConfigBean());
databaseDataSourceConnectionFactoryBean.setDataSource(dataSource);
databaseDataSourceConnectionFactoryBean.setSchema("public");
return databaseDataSourceConnectionFactoryBean;
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringRepositoryConfigurationTest.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = {"dbUnitDatabaseConnection"})
然后,您需要指定在测试中使用自定义IDatabaseConnection。这些连接将由bean“dbUnitDatabaseConnection”创建。例如,以下是我如何声明我的spring测试配置:
@Autowired
private DataSource dataSource;
@Bean
public DatabaseConfigBean databaseConfigBean() {
DatabaseConfigBean databaseConfigBean = new DatabaseConfigBean();
databaseConfigBean.setDatatypeFactory(new PostgresqlDataTypeFactory());
return databaseConfigBean;
}
@Bean(name = "dbUnitDatabaseConnection")
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() throws SQLException, DatabaseUnitException, IOException {
DatabaseDataSourceConnectionFactoryBean databaseDataSourceConnectionFactoryBean = new DatabaseDataSourceConnectionFactoryBean();
databaseDataSourceConnectionFactoryBean.setDatabaseConfig(databaseConfigBean());
databaseDataSourceConnectionFactoryBean.setDataSource(dataSource);
databaseDataSourceConnectionFactoryBean.setSchema("public");
return databaseDataSourceConnectionFactoryBean;
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringRepositoryConfigurationTest.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = {"dbUnitDatabaseConnection"})
这也是我的想法,但是将
FlatXmlDataSetLoader
配置为区分大小写并不能解决这个问题。需要注意的是,当删除属性\u id
列时,所有其他列都会毫无问题地插入。进一步的测试似乎表明这个问题与列的类型和默认值有关。不幸的是,我根本没有时间去发现根本原因。也许我太迟了,但是DbUnit不会识别任何特定于供应商的数据类型(例如uuid
),除非您明确指出。在您的例子中,应该使用org.dbunit.ext.postgresql.PostgresqlDataTypeFactory
的实例。
@Autowired
private DataSource dataSource;
@Bean
public DatabaseConfigBean databaseConfigBean() {
DatabaseConfigBean databaseConfigBean = new DatabaseConfigBean();
databaseConfigBean.setDatatypeFactory(new PostgresqlDataTypeFactory());
return databaseConfigBean;
}
@Bean(name = "dbUnitDatabaseConnection")
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() throws SQLException, DatabaseUnitException, IOException {
DatabaseDataSourceConnectionFactoryBean databaseDataSourceConnectionFactoryBean = new DatabaseDataSourceConnectionFactoryBean();
databaseDataSourceConnectionFactoryBean.setDatabaseConfig(databaseConfigBean());
databaseDataSourceConnectionFactoryBean.setDataSource(dataSource);
databaseDataSourceConnectionFactoryBean.setSchema("public");
return databaseDataSourceConnectionFactoryBean;
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringRepositoryConfigurationTest.class})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = {"dbUnitDatabaseConnection"})