单元测试Camel / RabbitMQ路由问题

时间:2018-04-27 11:05:34

标签: spring-boot rabbitmq apache-camel

我有问题单元测试一个使用rabbitmq代理经纪人的驼峰路线。

我已经研究了几个星期,但还没有找到一种有效的方法来做到这一点。

首先,我在测试中遇到了不调用rabbitmq 的问题,并将其作为单元测试而不是集成测试。这是通过使用 advicewith 并为模拟队列切换队列来实现的。

但是,使用以下代码,消息未到达结果或结束队列(MOBILE_QUEUE)。

java.lang.AssertionError: mock://result Received message count. Expected: <1> but was: <0> Expected :<1> Actual :<0>

这是我的路线,它导入rabbitmq.class

from(TEST_QUEUE).to(MOBILE_QUEUE).routeId("test2phone");

我的配置 rabbitmq.class

@Component
public class RabbitMQ extends Properties {

    public final String TEST_QUEUE = CreateRabbitMQQueue("TestQueue", "camel");
    public final String MOBILE_QUEUE = CreateRabbitMQQueue("MobileQueue", "camel");

    public static String CreateRabbitMQQueue(String QueueName, String RoutingKey)
    {
        String hostv;
        String portv;
        String username;
        String password;

        hostv = "mq-staging";
        portv = System.getenv("SERVICE_PORT_AMQP");
        username = System.getenv("V_RABBIT_USERNAME");
        password = System.getenv("V_RABBIT_PASSWORD");

        UriComponentsBuilder uriBuilder = UriComponentsBuilder
                .fromPath("/" )
                .scheme("rabbitmq")
                .host(hostv)
                .port(portv)
                .path("/" + QueueName)
                .queryParam("username",username)
                .queryParam("password", password)
                .queryParam("routingKey",RoutingKey)
                .queryParam("queue","Q" + QueueName);

        return uriBuilder.toUriString();
    }

}

我的单元测试

@RunWith(CamelSpringRunner.class)
@MockEndpoints
@UseAdviceWith
@SpringBootTest
public class RouteTester extends CamelTestSupport {

    String TEST_QUEUE;
    String MOBILE_QUEUE;

    @Autowired
    Routes routes;

    @Autowired
    CamelContext context;

    @Autowired
    ProducerTemplate template;

    @Before
    public void setUp() throws Exception {
        TEST_QUEUE = routes.getTEST_QUEUE();
        MOBILE_QUEUE = routes.getMOBILE_QUEUE();
        context.getRouteDefinition("test2phone").adviceWith(context, new Routes() {
            @Override
            public void configure() throws Exception {
                interceptSendToEndpoint(TEST_QUEUE)
                        .skipSendToOriginalEndpoint()
                        .to("mock:testQ");
                interceptSendToEndpoint(MOBILE_QUEUE)
                        .skipSendToOriginalEndpoint()
                        .to("mock:result");
            }
        });
        context.start();
    }

    @Test
    public void testTest() throws Exception {
        String body = "hello123";

        MockEndpoint resultEndpoint = context.getEndpoint("mock:result", MockEndpoint.class);

        resultEndpoint.expectedMessageCount(1);
        resultEndpoint.expectedBodiesReceived(body);
        template.sendBody(TEST_QUEUE, body);
        resultEndpoint.assertIsSatisfied();
    }

    @After
    public void TearDown() throws Exception {
        context.stop();
    }

}

1 个答案:

答案 0 :(得分:0)

interceptSendToEndpoint对拦截输出端点非常有用。您可能需要替换输入端点和拦截输出端点。请参阅AdviceWith

这应该有效:

context.getRouteDefinition("test2phone").adviceWith(context, new AdviceWithRouteBuilder() {
    @Override
    public void configure() throws Exception {
        replaceFromWith("direct:test");
        interceptSendToEndpoint(MOBILE_QUEUE)
            .skipSendToOriginalEndpoint()
            .to("mock:result");
        }
});

用以下方法测试你的路线:

template.sendBody("direct:test", body);