值得注意的是,这些测试在 Ubuntu 和服务器上完美运行,但在 Mac 和 Windows 上失败并出现相同的错误。
因此,在我的测试中,我使用此配置连接到 Maria 数据库:
@Configuration
public class EmbeddedDatabase {
@Autowired
private String defaultSchema;
@Bean
public MariaDB4jService mariaDB4jService() {
MariaDB4jSpringService mariaDB4jSpringService = new MariaDB4jSpringService();
DBConfigurationBuilder config = mariaDB4jSpringService.getConfiguration();
config.setPort(3310);
return mariaDB4jSpringService;
}
@Bean
public DataSource dataSource(MariaDB4jService mariaDB4jService) throws Exception {
mariaDB4jService.getDB().createDB(defaultSchema);
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(mariaDB4jService.getConfiguration().getURL(defaultSchema));
dataSource.setUsername("root");
dataSource.setPassword("");
dataSource.setDriverClassName("org.mariadb.jdbc.Driver");
return dataSource;
}
}
现在,默认架构已在我的 xml 配置文件中设置,它是:
<bean id="dbUnitDatabaseConnection" class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean"
<property name="schema" ref="defaultSchema" />
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="defaultSchema" class="java.lang.String">
<constructor-arg type="java.lang.String" value="test"/>
</bean>
这是所有测试类的父类:
@ContextConfiguration("classpath:test-repository-config.xml")
@TestExecutionListeners({ DbUnitTestExecutionListener.class })
@DbUnitConfiguration(dataSetLoader = RepositoryFlatXmlDataSetLoader.class)
public abstract class AbstractRepositoryTest
extends AbstractTransactionalJUnit4SpringContextTests {
}
我有这个自定义 RepositoryFlatXmlDataSetLoader 用于替换我在 xml 数据集中使用的“[NULL]”字段:
public class RepositoryFlatXmlDataSetLoader extends AbstractDataSetLoader {
private static Logger logger = LoggerFactory.getLogger(RepositoryFlatXmlDataSetLoader.class);
@Override
protected IDataSet createDataSet(Resource resource) throws Exception {
FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
builder.setColumnSensing(true);
try (InputStream inputStream = resource.getInputStream()) {
return createReplacementDataSet(builder.build(inputStream));
}
catch(Throwable thrh){
logger.error("Failed to create dataset");
throw thrh;
}
}
private ReplacementDataSet createReplacementDataSet(FlatXmlDataSet dataSet) {
ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet);
//Configure the replacement dataset to replace '[null]' strings with null.
replacementDataSet.addReplacementObject("[null]", ITable.NO_VALUE);
replacementDataSet.addReplacementObject("[NULL]", ITable.NO_VALUE);
return replacementDataSet;
}
}
这是我的数据集 xml 文件之一 - officeRepositoryData.xml:
<dataset>
<cfr_office ID="1" ORG_NAME="demo" IS_DEFAULT="true"/>
<cfr_office ID="2" ORG_NAME="test" IS_DEFAULT="false"/>
</dataset>
例如,这是测试之一:
@NotThreadSafe
@DatabaseSetup(value = "officeRepositoryData.xml", type = DatabaseOperation.CLEAN_INSERT)
@DatabaseTearDown(value = "officeRepositoryData.xml", type = DatabaseOperation.DELETE_ALL)
public class OfficeRepositoryTest extends AbstractRepositoryTest {
@Autowired
private OfficeRepository officeRepository;
@Test
public void testDefaultOfficeFound() {
List<Office> offices = officeRepository.findDefault();
assertTrue(isNotEmpty(offices));
Office office = offices.get(0);
assertEquals("demo", office.getOrganizationName());
assertTrue(office.getIsDefault());
}
}
那么,当我运行测试时会发生什么...... 所有表都是在 JPA 中创建的,我在 eclipse 控制台和创建了 MariaDB 连接的数据库透视图中看到它,然后当 dbUnit 开始为测试准备数据集时,我收到错误。这是它的堆栈跟踪以及之前的一些行,这些行可能很重要(或不重要,不确定):
INFO o.s.t.c.t.TransactionContext - Began transaction (1) for test context [DefaultTestContext@305e95a4 testClass = OfficeRepositoryTest, testInstance = com.sumac.nots.repository.api.OfficeRepositoryTest@55e42684, testMethod = testDefaultOfficeFound@OfficeRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@2a5c6b76 testClass = OfficeRepositoryTest, locations = '{classpath:test-repository-config.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@7f22687e]; rollback [true]
11:49:33.775 [main] WARN o.d.d.AbstractTableMetaData - Potential problem found: The configured data type factory 'class org.dbunit.dataset.datatype.DefaultDataTypeFactory' might cause problems with the current database 'MySQL' (e.g. some datatypes may not be supported properly). In rare cases you might see this message because the list of supported database products is incomplete (list=[derby]). If so please request a java-class update via the forums.If you are using your own IDataTypeFactory extending DefaultDataTypeFactory, ensure that you override getValidDbProducts() to specify the supported database products.
11:49:42.306 [main] WARN o.d.d.DatabaseTableMetaData - No columns found for table 'cfr_office' that are supported by dbunit. Will return an empty column list
11:49:48.098 [main] WARN o.s.t.c.TestContextManager - Caught exception while allowing TestExecutionListener [com.github.springtestdbunit.DbUnitTestExecutionListener@66d3eec0] to process 'before' execution of test method [public void com.sumac.nots.repository.api.OfficeRepositoryTest.testDefaultOfficeFound()] for test instance [com.sumac.nots.repository.api.OfficeRepositoryTest@55e42684]
org.dbunit.dataset.NoSuchColumnException: cfr_office.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:150)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
at com.github.springtestdbunit.DbUnitRunner.setupOrTeardown(DbUnitRunner.java:183)
at com.github.springtestdbunit.DbUnitRunner.beforeTestMethod(DbUnitRunner.java:75)
at com.github.springtestdbunit.DbUnitTestExecutionListener.beforeTestMethod(DbUnitTestExecutionListener.java:185)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:269)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
通常,出现此类错误的原因是该列在某处丢失,或者该列存在一些区分大小写的问题,我在代码中进行了深入调试,在我看来,对于这种特殊情况,我遇到了一些其他问题。但我不确定。
看起来dbUnit在代码深处创建了一些columnList,从一些结果集中获取有关数据库的一些信息。如果所有信息都与目录、schema_name 和 table_name 匹配,则感觉此列列表包含列值。但在调试中 shema_name 为 null,因此无法创建列列表,然后无法找到第一列 - 即 ID。 如果我写的最后一段很乱,请不要计较。
最佳答案
我会尝试使用小写的列名称:
<dataset>
<cfr_office id="1" org_name="demo" is_default="true"/>
<cfr_office id="2" org_name="test" is_default="false"/>
</dataset>
关于java - DBUnit 测试给出了 MariaDB 的 NoSuchColumnException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50879256/