我正在尝试使用 spring test dbunit
。
https://springtestdbunit.github.io/spring-test-dbunit/
当我使用弹簧4.1.x
时,我决定将1.2.1
版本用于spring-test-dbunit
,而2.5.2
用于COR dbunit
。
最初我使用了普通的dbunit
,并且效果很好。然后我决定尝试spring-test-dbunit
,然后遇到了几个问题。
这是我的测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {
"classpath:path/to/test/context/sql-context.xml"})
@TransactionConfiguration(defaultRollback = true)
@Transactional
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = "databaseConnection")
@DatabaseSetup("classpath:path/to/dataset/questionRepositoryTestDS.xml")
public class QuestionRepositoryDbUnitTest {
....
@Autowired
private QuestionRepository repository;
@Test
public void mustReturnQuestion() throws Exception {
....
assertEquals("Result is not the same as expected!", expected,
repository.findQuestion(QUESTION_ID_1, PRODUCT_CONFIGURATION_ID_1, LANGUAGE));
}
我的数据集文件看起来像
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<question question_id='q_mail' display_type='EMAIL' display_group='2' organization_uid='123' display_order='1'/>
<question question_id='q_copies' display_type='NUMBER' display_group='1' organization_uid='123' display_order='1'/>
<localized_question question_id='q_mail' language='EN' organization_uid='*' display_label='What is your email?'/>
<localized_question question_id='q_mail' language='EN' organization_uid='123' display_label='Enter the mailbox'/>
<localized_question question_id='q_copies' language='EN' organization_uid='*' display_label='How many copies you are planning to create?'/>
<localized_values question_select_value_id='a_mail1' language='EN' organization_uid='*' display_label='common@email.com'/>
<localized_values question_select_value_id='a_mail1' language='EN' organization_uid='123' display_label='custom@email.com'/>
<localized_values question_select_value_id='a_mail2' language='EN' organization_uid='*' display_label='null@email.com'/>
</dataset>
数据库连接bean看起来像
<bean id="databaseConnection"
class="com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean">
<property name="schema" value="mySchema"/>
<property name="dataSource" ref="customDataSource"/>
</bean>
dataSource
bean是
<bean id="customDataSource"
class="com.custom.db.embedded.EmbeddedH2DatabaseFactory">
<property name="resourcesFromPaths">
<list value-type="java.lang.String">
<value>#{systemProperties['test-changelog']}</value>
</list>
</property>
<property name="url" value="jdbc:h2:mem:product.pricing;MVCC=TRUE"/>
<property name="createCommonTablesOnStartup" value="false"/>
</bean>
但是当我尝试运行测试时,我会得到此错误
org.dbunit.dataset.NoSuchTableException: localized_values
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:305)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:109)
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:186)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:249)
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:70)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
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:163)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
有什么问题?
当我使用普通dbunit
时,我必须设置autoCommit
才能使它起作用
databaseConnection = new DatabaseConnection(h2databaseResource.getConnection(), DATABASE_SCHEMA);
databaseConnection.getConnection().setAutoCommit(true);
(尽管我认为autoCommit
应该为true
)
我知道这是一个较晚的答案,但我认为您的问题是您尚未正确创建模式。我看到您正在使用自定义数据源工厂,我建议您切换到使用更标准化的DB初始化,例如将其放入测试XML配置中:
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
</jdbc:initialize-database>
或声明测试@Configuration
类:
@Configuration
public class TestDbConfig {
@Value("classpath:com/foo/sql/db-schema.sql")
private Resource schemaScript;
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(schemaScript);
return populator;
}
}