2015-01-22 2 views
7

Я написал пользователя RabbitMQ, реализовав интерфейс MessageListener и установив SimpleMessageListenerContainer. Он работает хорошо, когда я тестирую его вручную. Теперь я хотел бы написать тест интеграции, что:RabbitMQ Integration Test and Threading

  1. Создает сообщение
  2. выталкивает сообщение на мой RabbitMQ сервер
  3. Ждет пока сообщение потребляются моей реализацией MessageListener
  4. Test делает некоторые утверждают как только все сделано

Однако, поскольку мой MessageListener работает в отдельном потоке, это затрудняет тестирование модулей. Использование Thread.sleep в моем тесте для ожидания MessageListener является ненадежным, мне нужен какой-то подход блокировки.

Настройка очереди ответа и использование rabbitTemplate.convertSendAndReceive Мой единственный вариант? Я не хотел настраивать очереди ответов, так как они не будут использоваться в реальной системе.

Есть ли способ сделать это, используя только rabbitTemplate.convertAndSend, а затем как-то ждет, когда мой MessageListener получит сообщение и обработает его? В идеале, я бы себе представить, что-то вроде этого:

rabbitTemplate.convertAndSend("routing.key", testObject); 
waitForListner() // Somehow wait for my MessageListener consume the message 
assertTrue(...) 
assertTrue(...) 

Я знаю, что я мог бы просто передать сообщение непосредственно к моему MessageListener без подключения к RabbitMQ на всех, но я надеялся, чтобы проверить всю систему, если это возможно сделать так. Я планирую вернуться к этому решению, если нет возможности эффективно выполнить мою цель.

ответ

4

Есть несколько подходов, проще всего в том, чтобы обернуть слушателя и передать в CountDownLatch который отсчитывается вниз от слушателя и основной тест нить использует

assertTrue(latch.await(TimeUnit.SECONDS)); 

Вы также можете передать обратно фактическое полученное сообщение поэтому вы можете проверить, что это так, как ожидалось.

Также см. integration test cases in the framework itself.

+0

Этот подход работал хорошо для меня и был довольно ненавязчивым. Некоторые из объяснений этого сообщения http://stackoverflow.com/questions/17827022/what-is-countdown-latch-in-java-multithreading также были полезны. –

+2

@GaryRussell Что делать, если у вас есть существующий класс Listener, и вы хотите избежать добавления 'CountDownLatch' только для тестирования? Есть ли обходной путь для тестирования интеграции в этом случае? – Glide

+0

Вы можете добавить совет к контейнеру слушателя; см. [обсуждение в этом вопросе/ответе] (http://stackoverflow.com/questions/34454159/how-to-write-an-integration-test-for-rabbitlistener-annotation/34454922#34454922) и [тестовый пример Я добавил в рамки] (https://github.com/spring-projects/spring-amqp/pull/353). Они сосредоточены вокруг '@ RabbitListener', но применяются те же методы. У меня есть [работа здесь] (https://github.com/garyrussell/spring-amqp/commit/045b7494b250a41061dab02c845db3a2c3bccb0e), чтобы формализовать механизм добавления таких советов для сценариев сценариев. –