我正在实施一个消息翻译模式 http://camel.apache.org/message-translator.html使用 Apache Camel,使用来自 RESTful 端点的消息并将它们发送到 AMQP 端点。
封闭的应用程序基于 Spring Boot,因此我使用 Camel 的“弹簧靴 http://camel.apache.org/spring-boot.html“集成两个框架的组件。正如这个 spring-boot 链接中的文档所建议的,我正在一个内部实现我的 Camel 路由@Configuration
-带注释的类扩展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 路由的典型方法是将路由剪切粘贴到单元测试中,并将一个或多个端点 URL 替换为“mock:whatever
".
我猜可能是sorta有效...但它非常脆弱,当有人稍后更改真实代码而不更新单元测试时,您的测试套件将无法识别。
我尝试使用模拟来调整一些基于 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
的,因为您显然无法将“真实”端点 URL 注入到MockEndpoint
实例(仅 URL 前缀为“mock:
").
当我使用“mock:...
“在我的单元测试中使用端点 URL,那么它就没用了,因为没有任何东西将它绑定到被测类中的真实端点 URL。因此,真实端点 URL 永远不会被覆盖。当执行真实代码时,它只是使用真实端点作为正常(目标是能够在不依赖 RabbitMQ 的外部依赖的情况下进行测试)。
我在这里遗漏了一些非常基本的东西吗?似乎有一种方法可以让单元测试将假路由注入到这样的类中,这样被测试的代码就可以在没有意识到的情况下从真实端点切换到模拟端点。或者,我想我可以重构我的代码,以便匿名Processor
被提升为一个独立的类......然后我可以独立于路线来单元测试其翻译逻辑。但这似乎是一个不完整的测试。