如何在单独的camel上下文中模拟camel端点

时间:2014-12-19 19:01:32

标签: apache-camel

我正在为一个隐藏最终用户的骆驼业务的库编写测试用例。 该库公开了诸如sendMessages()等方法,并在内部使用ProducerTemplate将消息发送到camel路由,在这些路由中它们被聚合并最终发送到目的地。

我希望能够编写调用库方法的测试并模拟camel路由端点以便稍后对其进行断言。

如果我使用CamelSpringTestSupport,它基本上会创建一个新的ClassPathXmlApplicationContext,使用它我可以测试路由。

但是我想测试在库的camel context中创建的端点,以及我测试覆盖库代码。

可以这样做吗?

2 个答案:

答案 0 :(得分:3)

使用Camel的AdviceWith动态更改路由行为(拦截交换并发送到模拟端点进行验证等)......它非常灵活,可以利用熟悉的MockEndpoints等...

例如......拦截发送到direct:start路径的消息

context.getRouteDefinition("myRouteId").adviceWith(context, new AdviceWithRouteBuilder() {
    @Override
    public void configure() throws Exception {
       interceptSendToEndpoint("direct:start")
                .skipSendToOriginalEndpoint()
                .to("mock:start");
    }
});

getMockEndpoint("mock:start").expectedBodiesReceived("Hello World");

答案 1 :(得分:0)

我的最终测试用例如下所示,其中现有的上下文路由被模拟。

import org.apache.camel.Exchange;
import org.apache.camel.builder.AdviceWithRouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.spring.CamelSpringTestSupport;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.test.annotation.DirtiesContext;
import java.net.URL;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyAppTest extends CamelSpringTestSupport {

private static MyApp myapp;
protected final Logger log = LoggerFactory.getLogger(MyAppTest.class);

@Override
protected AbstractApplicationContext createApplicationContext() {
    return (AbstractApplicationContext) myApp.getContext();
}

@Override
public boolean isUseAdviceWith() {
    // tell we are using advice with, which allows us to advice the route
    // before Camel is being started, and thus can replace myApp Endpoint with something else.
    return true;
}

@BeforeClass
public static void oneTimeSetUp() throws Exception {
    myApp = new myApp();
}

@Test
@DirtiesContext
public void test01() throws Exception {

    log.info("TEST: Going to apply advideWith clause to existing route");

    context.getRouteDefinition("bulkIndexRoute").adviceWith(context, new AdviceWithRouteBuilder() {
        @Override
        public void configure() throws Exception {

            weaveByToString(".*myAppEndpoint.*")
                    .replace()
                    .aggregate(header("ABC"), new ArrayListAggregationStrategy())
                    .completionSize(100)
                    .completionInterval(1000)
                    .to("mock:foo");
        }
    });
    log.info("TEST: Done applying adviceWith Clause");

    MockEndpoint mockedES = getMockEndpoint("mock:foo");
    mockedES.expectedMessageCount(2);
    mockedES.setAssertPeriod(10000);

    // Create 150 test documents and index them
    for(int i = 0; i < 150; i++) {
        Map<String, String> d = new HashMap<String, String>();
        d.put("key1", "value" + i);
        d.put("key2", "value" + i);
        myApp.send("param1", "param2", d);
    }

    mockedES.assertIsSatisfied();

    int count = 0;
    for(Exchange ex : mockedES.getExchanges()){
        List<Map<String, Object>> documentList = ex.getIn().getBody(List.class);
        count += documentList.size();
    }

    Assert.assertEquals("Received back 150 message", 150, count);
}

}

MyApp类将上下文返回给测试,以便可以模拟运行上下文中的路由。