我使用Spring在不同的xml中有两个驼峰上下文(A和B)。当我只加载一个上下文我的junit工作,但当我尝试加载两个上下文时,Endpoint注入失败运行junit。
那么,有人有一个示例如何使用Spring camel使用多个上下文进行测试吗?
春季测试
public class BaseSpringTest extends CamelSpringTestSupport
{
protected AbstractXmlApplicationContext createApplicationContext()
{
return new ClassPathXmlApplicationContext("camel-config.xml");
}
}
我的档案camel-config.xml
<beans>
<context:annotation-config/>
<import resource="classpath:camel-test-dao.xml" />
<import resource="classpath:camel-contextA.xml"/>
<import resource="classpath:camel-contextB.xml"/>
</beans>
我的背景:
<camelContext xmlns="camel.apache.org/schema/spring" id="contextA">
...
</camelContext>
<camelContext xmlns="camel.apache.org/schema/spring" id="contextB">
...
</camelContext>
我的单元测试,无法注入Endpoint
:
@EndpointInject(uri = "direct:myroute", context="contextB")
private Endpoint eFooTest;
堆栈跟踪:
org.apache.camel.spring.GenericBeansException: Error post processing bean: com.mycompany.test.FooTest; nested exception is java.lang.NullPointerException
at org.apache.camel.spring.CamelBeanPostProcessor.postProcessBeforeInitialization(CamelBeanPostProcessor.java:154)
at org.apache.camel.test.spring.CamelSpringTestSupport.postProcessTest(CamelSpringTestSupport.java:62)
at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:319)
at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:238)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
at org.apache.camel.impl.CamelPostProcessorHelper.matchContext(CamelPostProcessorHelper.java:84)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor$1.doWith(DefaultCamelBeanPostProcessor.java:181)
at org.apache.camel.util.ReflectionHelper.doWithFields(ReflectionHelper.java:73)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor.injectFields(DefaultCamelBeanPostProcessor.java:168)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor.postProcessBeforeInitialization(DefaultCamelBeanPostProcessor.java:82)
at org.apache.camel.spring.CamelBeanPostProcessor.postProcessBeforeInitialization(CamelBeanPostProcessor.java:148)
... 31 more
显然CamelBeanPostProcessor存在一个错误,当有一个上下文时,返回一个空值!
if(contexts!= null&amp;&amp; contexts.size()== 1){
@XmlTransient
private final DefaultCamelBeanPostProcessor delegate = new DefaultCamelBeanPostProcessor() {
@Override
public CamelContext getOrLookupCamelContext() {
if (camelContext == null) {
if (camelId != null) {
LOG.trace("Looking up CamelContext by id: {} from Spring ApplicationContext: {}", camelId, applicationContext);
camelContext = applicationContext.getBean(camelId, CamelContext.class);
} else {
// lookup by type and grab the single CamelContext if exists
LOG.trace("Looking up CamelContext by type from Spring ApplicationContext: {}", applicationContext);
Map<String, CamelContext> contexts = applicationContext.getBeansOfType(CamelContext.class);
if (contexts != null && contexts.size() == 1) {
camelContext = contexts.values().iterator().next();
}
}
}
return camelContext;
}
Camel 2.16.2
Spring 4.1.5
JDK 1.7
JDK 1.8
答案 0 :(得分:0)
我一直在努力解决这个问题。最后,我设法了解了一个解决方法,它允许我使用生产中使用的原始路径xml文件,但结合到一个camel上下文中,以便能够将其用于测试。这样我就可以为bean端点注入模拟,并通过在模拟上声明来检查整个过程。
有两种不同的捆绑包。一个来自发票,另一个来自电子邮件。这些路线协调了这个过程。
首先,我将生产xml文件上的路由外部化。发票捆绑包的Spring上下文( invoicing-spring-context.xml )和路由( invoicing-routes.xml )文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="invoicingCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="invoicingRoutes"/>
</camelContext>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<routeContext id="invoicingRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="planner" autoStartup="true">
<from uri="quartz://planner?cron=0+0+23+16+*+?" />
<to uri="direct:invoicing" />
</route>
<route id="invoicing" autoStartup="true">
<from uri="direct:invoicing?exchangePattern=InOut" />
<to uri="bean:invoicer?method=generateInvoices" />
<to uri="direct-vm:emailing" />
</route>
</routeContext>
</beans>
用于通过电子邮件发送捆绑包的Spring上下文( emailing-spring-context.xml )和路由( emailing-routes.xml ):
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="emailingCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="emailingRoutes"/>
</camelContext>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<routeContext id="emailingRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="emailing" autoStartup="true">
<from uri="direct-vm:emailing" />
<to uri="bean:emailer?method=createEmails" />
<to uri="bean:emailer?method=sendEmails" />
</route>
</routeContext>
</beans>
然后出于测试目的,我创建了另一个弹簧上下文( complete-process-test-spring-context.xml ),它导入了两个路径文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="completeProcessTestCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="invoicingRoutes"/>
<routeContextRef ref="emailingRoutes"/>
</camelContext>
</beans>
测试类看起来像:
public class CompleteProcessTest extends CamelSpringTestSupport {
@Test
public void completeProcess() {
...
invoicerMock.generateInvoices(EasyMock.isA(Exchange.class));
emailerMock.createEmails(EasyMock.isA(Exchange.class));
emailerMock.sendEmails(EasyMock.isA(Exchange.class));
EasyMock.replay(invoicerMock);
EasyMock.replay(emailerMock);
this.template.requestBody(this.context.getEndpoint("direct://invoicing"), "");
EasyMock.verify(invoicerMock);
EasyMock.verify(emailerMock);
}
@Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("classpath:/META-INF/spring/invoicing-routes.xml",
"classpath:/META-INF/spring/emailing-routes.xml",
"classpath:/META-INF/spring/complete-process-test-spring-context.xml");
}
...
}
答案 1 :(得分:0)
感谢@ Jorge-c,但是使用routeContext,我们连续只有一个CamelContext。
要在单元测试中使用乘法上下文,请不要使用CamelSpringTestSupport,否则会出现错误。
public class BaseSpringTest extends CamelSpringTestSupport {...}
使用“@RunWith(SpringJUnit4ClassRunner.class)”
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/camel-my-root-spring-config.xml")
public class BaseSpringJUnit4
{
@EndpointInject(uri = "direct:myroute", context="contextB")
private Endpoint eFooTest;
}
这个有效! 不要忘记在端点注释中加上explicitilly context =“contextB”
Camel 2.16.2
Spring 4.1.5
JDK 1.7
JDK 1.8