我使用camel.version 2.18.1和spring-boot 1.5.1.REASE。
我有一些或多或少复杂的camel路由,在这些路由中,来自MQ主题的消息将被消耗、过滤、转换,并最终路由到不同的MQ主题。
from("{{sourceEP}}").to("{{archiveEP}}")
.process(new MyProcessor())
.to("{{archiveEP}}").to("{{resultEP}}");
应用程序属性
sourceEP=jms:topic:SOURCE
archiveEP=jms:topic:ARCHIVE
resultEP=jms:topic:TARGET
对于每条路线,存在超过40种不同的场景。因此,我对每条路由都有近50个JUnit测试,总共有近400个JUnitTest,我使用maven-surefire插件运行这些测试以实现并行测试执行。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>4</threadCount>
</configuration>
</plugin>
问题是,当JUnit测试并行运行时,这将导致生产者端点不一致(EDIT:对于测试,我使用Camel中的Mock端点(。并行测试影响了其他测试,并且目标终结点中预期的消息数不正确。
测试:应用程序属性
sourceEP=direct:start
archiveEP=mock:archive
resultEP=mock:result
RouteTest.java
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class RouteTest {
@Autowired
private CamelContext context;
@EndpointInject(uri = "{{archiveEP}}")
protected MockEndpoint archiveEndpoint;
@EndpointInject(uri = "{{resultEP}}")
protected MockEndpoint resultEndpoint;
@Produce(uri = "{{sourceEP}}")
protected ProducerTemplate sourceEndpoint;
@Before
public void setup() {
sourceEndpoint.cleanUp();
archiveEndpoint.reset();
resultEndpoint.reset();
}
@Test
public void test1() throws Exception {
sourceEndpoint.sendBody("some text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("expected output");
}
@Test
public void test2() throws Exception {
sourceEndpoint.sendBody("another text");
archiveEndpoint.expectedMessageCount(2);
archiveEndpoint.assertIsSatisfied();
resultEndpoint.expectedMessageCount(1);
resultEndpoint.assertIsSatisfied();
resultEndpoint.expectedBodiesReceived("another output");
}
...
}
我的问题是,有可能并行运行Camel路线的JUnit测试吗?
我试图在测试方法上添加@DirtiesContext
,以强制Spring Testing在每个测试方法之后自动重新加载CamelContext:http://camel.apache.org/testing.html
当然,这在并行测试执行中不起作用,因为结果仍然是随机的,并且预期的消息数量是不正确的。
我最终设置了这些测试,这些测试将测试到@NotThreadSafe
的Camel路由,以强制执行单线程。只有这些将测试Camel路由之外的其他功能的JUnit测试是并行执行的。
但是,对于近400个JUnit测试的数量来说,这并不是一个令人满意的解决方案
是否有任何配置或设置可以并行测试Camel路线,从而正确工作?
您的MQ主题是有状态的,因此"不是线程安全的"。一旦多个测试并行运行,主题中的消息数量就无法预测。
为了解决这个问题,您必须隔离测试的有状态部分,即MQ主题。您必须为每个测试生成唯一的MQ主题名称,以便每个测试都有自己的MQ主题。如果是这种情况,那么消息大小的定义就像在单线程执行中一样好。
或者,作为主题内隔离的替代方案,您可以使用JMS消息选择器来为不同的测试隔离主题中的消息。在这种情况下,每个测试都必须设置一个具有唯一值的消息头,并且只使用具有该值的消息。