我正在使用 Apache Camel 实现消息转换器模式,以使用来自 RESTful 端点的消息并将它们发送到 AMQP 端点。
封闭的应用程序基于 Spring Boot,因此我使用 Camel 的“ spring-boot ”组件来集成这两个框架。正如这个 spring-boot 链接中的文档所建议的那样,我在一个@Configuration
-annotated 类中实现了我的 Camel 路由,该类扩展了RouteBuilder
:
@Component
public class MyRestToAmqpRouter extends RouteBuilder {
@Override
public void configure() throws Exception {
from("jetty:http://my-restful-url")
.process(exchange -> {
// convert the message body from JSON to XML, take some
// incoming header values and put them in the outgoing
// body, etc...
}).to("rabbitmq://my-rabbitmq-url");
}
}
我的问题涉及如何在不需要实际的 RESTful 端点或配置的 RabbitMQ 代理的情况下对该翻译进行单元测试?我已经阅读了许多在线示例,以及Camel in Action书……似乎对 Camel 路线进行单元测试的典型方法是将路线剪切粘贴到您的单元测试中,并替换一个或更多带有“”的端点 URL mock:whatever
。
我想这有点工作......但它非常脆弱,当有人稍后更改真实代码而不更新单元测试时,您的测试套件将无法识别。
我尝试使用模拟来调整一些基于 Spring 的单元测试示例,如下所示:
@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Application.class})
public class MyRestToAmqpRouterTest extends AbstractJUnit4SpringContextTests {
@Produce(uri = "jetty:http://my-restful-url")
private ProducerTemplate fakeRest;
@EndpointInject(uri = "rabbitmq://my-rabbit-url")
private MockEndpoint fakeRabbit;
@Test
@DirtiesContext
public void testRouter() throws InterruptedException {
fakeRabbit.expectedMessageCount(1);
fakeRest.sendBodyAndHeader("", "header-1", "some value");
fakeRabbit.assertIsSatisfied();
}
}
我希望 Camel 会从单元测试中获取这些端点 URL,将它们注册为模拟......然后在真实代码尝试使用这些 URL 时使用模拟而不是真实端点。
但是,我不确定这是可能的。当我在单元测试中使用真实的 URL 时,我得到了IllegalArgumentException
's,因为您显然无法将“真实”端点 URL 注入MockEndpoint
实例(只有以“ mock:
”为前缀的 URL)。
当我mock:...
在单元测试中使用“”端点 URL 时,它就没有用了,因为没有任何东西将它与被测类中的真实端点 URL 联系起来。因此,真正的端点 URL 永远不会被覆盖。当真正的代码被执行时,它只是像往常一样使用真正的端点(目标是能够在没有外部依赖于 RabbitMQ 的情况下进行测试)。
我在这里错过了一些真正基础的东西吗?似乎有一种方法可以让单元测试将假路由注入到这样的类中,这样被测代码甚至可以在没有意识到的情况下从真实端点切换到模拟端点。或者,我想我可以重构我的代码,以便将匿名Processor
提升到一个独立的类......然后我可以独立于路由对它的翻译逻辑进行单元测试。但这似乎是一个不完整的测试。