集成测试RabbitMQ listner-间歇性失败,因为消息需要花费时间才能排队

时间:2019-02-08 15:32:17

标签: spring-rabbitmq integration-testing

我已经使用RabbitMock为以下流程编写了集成测试(在github上找到了它,看起来真的很酷):

消息被添加到传入消息队列->传入消息列表器拾取消息->处理它->将新的传出消息放入新队列中传出消息队列->(仅用于测试)在src / test / resources中为此传出队列编写了一个列表器。

一切正常(有一个重要的小故障-间歇性超时),我正在执行以下断言:

List<OutgoingData> receivedMessages = new ArrayList<>();
            assertTimeoutPreemptively(ofMillis(15000L), () -> {
                    while (receivedMessages.isEmpty()) {
                        OutgoingData data = 
receiver.getOutgoingData();
                        if(data != null){
                            receivedMessages.add(data);
                        }

                    }
                }
            );

            assertThat(receivedMessages.get(0)).isNotNull();

 assertThat
(receivedMessages.get(0).getRecipient())
.isEqualTo("enabled@localhost");

此测试中的超时是我面临的真正问题。

  1. 由于超时,测试变得越来越慢。
  2. 如果我取消超时,则测试将卡在Jenkins中,需要强行终止。
  3. 有时,这15000毫秒的超时时间还不够,并且测试失败。

我想知道在集成测试中是否有更好的方法来处理这种情况。

期待您的投入。

非常感谢, Banyanbat

1 个答案:

答案 0 :(得分:0)

当我稍加思考并与我的一位团队成员进行了交谈时,它使我想到可以在此处有效使用Java 8期货。

我实现了它,如下所示,它就像一个魅力。

@Test
public void basic_consume_case()
        InterruptedException, ExecutionException {
    IncomingData incomingData = new IncomingData();
    incomingData.setRecipient("enabled@localhost");
    incomingData.setSender("unblocked@localhost");
    incomingData.setStoreKey("123");
    incomingData.setSubject("Hello");
    incomingData.setText("Hello from Test 1");
    try (AnnotationConfigApplicationContext context = new 
   AnnotationConfigApplicationContext(
            ConnectionFactoryConfiguration.class)) {

        sendMessage(incomingData);

        Future<OutgoingData> receivedMessageFuture = pollOutgoingQueueForData();

        OutgoingData receivedMessage = receivedMessageFuture.get();

        assertThat(receivedMessage).isNotNull();
        assertThat(receivedMessage.getRecipient()).isEqualTo("enabled@localhost");
        assertThat(receivedMessage.getContent())
        ...

    }
}
private void sendMessage(IncomingData incomingData) {
    try {
        rabbitTemplate.convertAndSend("incoming-data-queue", incomingData, m -> {
            m.getMessageProperties().setContentType("application/json");
            return m;
        });

    } finally {
    }
}

private Future<OutgoingData> pollOutgoingQueueForData() throws InterruptedException {

    return executor.submit(() -> {
        OutgoingData receivedMessage = null;
        while (receivedMessage == null) {
            receivedMessage = (OutgoingData) 
rabbitTemplate.receiveAndConvert("outgoing-queue");
        }
        return receivedMessage;
    });

}