我正在努力进行一项有效的junit测试,以回滚在camel路由期间发生的操作。
我有一个侦听目录的camel路由设置。它期待一个csv文件。当csv文件出现时,它会创建新的SearchAnalytics数据。它在csv文件中的每一行中向表中添加一个新行。
我放置的默认spring事务方法似乎不适用于camel路由上发生的操作。
以下代码有效。但是,它会永久保存数据,并且不会回滚插入数据。这意味着测试只会传递一次,除非我手动删除数据。
鉴于我的示例代码如何使其回滚事务?
我的路线看起来像这样
from("ftp://some__remote__ftp_dir_path")
.routeId("searchAnalyticsImport")
.choice()
.when(simple("${in.header.CamelFileName} contains '.csv'"))
.split().method("csvSplitter", "iterator").streaming() // reads the csv file returns data objects
.processRef("searchAnalyticsProcesser") // this some dao saves
.to(Queues.SOME_REQUEST)
.end();
Junit测试
@TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { TestAppConfig.class})
public class searchAnalyticsImportTest {
@EndpointInject(uri = "mock:sippmatcher.requestqueue?preserveMessageQos=true")
private MockEndpoint mockEndpointRequest;
@Before
public void setup() throws Exception {
camelContext.getRouteDefinition("searchAnalyticsImport").adviceWith(camelContext, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
replaceFromWith("file://"+this.getClass().getResource("path to folder etc...")+"?noop=true");
interceptSendToEndpoint(Queues.SOME_REQUEST)
.skipSendToOriginalEndpoint()
.to(mockEndpointRequest);
}
});
}
@Test
public void simpleTest() throws Exception{
// there are 2 results in the test csv file.. need to poll the results till it completes
PollWithTimeout.run("keep polling until route has been statisfied", 15000, new PollWithTimeout.Attempt() {
@Override
public boolean complete() {
Date dateTime1MinuteAgo = new DateTime().minusMinutes(1).toDate();
Integer newSearchCount = searchAnalysiticDao.findBySearchStartedAfter(dateTime1MinuteAgo).size();
System.out.println("Recently added count: " + newSearchCount);
return (newSearchCount == 2);
}
});
mockEndpointRequest.expectedMessageCount(2);
mockEndpointRequest.assertIsSatisfied();
}
}
答案 0 :(得分:1)
将bean添加到Context (将为此添加javaconfig选项)
如Andreas的评论部分所述,您可以将.transacted添加到路由中,并确保将事务管理器bean注入上下文文件中。
<强>路线强>
from("ftp://some__remote__ftp_dir_path")
.routeId("searchAnalyticsImport")
.end()
.transacted("PROPAGATION_REQUIRED")
etc....
Context Bean配置
<bean id="jmsTransactionManager"
class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="pooledConnectionFactory" />
<property name="defaultTimeout" value="30"/>
</bean>
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="jmsTransactionManager" />
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>
或者将事务添加到dao
您可以在 searchAnalyticsProcesser 中调用的dao方法中使用以下注释。仍然需要事务maanger bean,但您可以在注释中按名称指定它。
@Transactional(
propagation = Propagation.REQUIRED,
readOnly = false,
value="transactionManager",
rollbackFor = {
Exception.class
})
public void insertStuff()