Привет, у меня есть интеграционный тест с докером с использованием тестовых контейнеров. В контейнере запускаю jms. В тесте я помещаю сообщение в очередь.
Как я могу подождать в тесте, чтобы заполнить его на jms?
На локальном компьютере он работает, но на jenkins не работает, поэтому мне нужно добавить
Thread.sleep(3000);
но это мерзко. org.awaitility, похоже, упускается из виду:
await().atMost(2, TimeUnit.SECONDS).until(() -> return true));
Мне просто нужно сделать паузу, чтобы jms распространялся (поместил в очередь jms) и дождался действия слушателя, который помещает сообщение в базу данных. Затем мне нужно вызвать конечную точку отдыха, чтобы убедиться, что она работает.
С темой было бы проще, потому что я бы создал тестовый слушатель по теме. Но это очередь, может быть слушатель, который получит сообщение.
Спасибо заранее за любые предложения
Использование sleep() не идеально, потому что он хрупкий и неэффективный. Он хрупкий, потому что, если машина еще больше замедлится, продолжительности сна все равно будет недостаточно. Это неэффективно, потому что, если машина ускоряется, она будет спать без причины. Это действительно может сложиться в результате множества тестов.


Используйте повторные попытки (например, Spring RetryTemplate или Политика отказоустойчивой повторной попытки), чтобы сократить время выполнения интеграционного теста:
Вот пример ожидания записи в БД; настройте политики в соответствии с вашими потребностями:
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setBackOffPolicy(new FixedBackOffPolicy());
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(
10, Collections.singletonMap(AssertionError.class, true)));
retryTemplate.execute(retryContext -> {
List<MyRecord> records = jdbcTemplate.query("select ...");
Assert.assertEquals(1, records.size());
return null;
});
Используйте org.awaitility с JMS QueueBrowser, например:
@Test
public void myTest() throws Exception {
...
await().atMost(2, TimeUnit.SECONDS).until(() -> return queueIsEmpty(queueName)));
...
}
private boolean queueIsEmpty(String queueName) {
ConnectionFactory cf = new MyBrokersConnectionFactory();
Connection connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
QueueBrowser browser = session.createBrowser(session.createQueue(queueName));
Enumeration enumeration = senderBrowser.getEnumeration();
while (enumeration.hasMoreElements()) {
return false;
}
return true;
}
QueueBrowser - это только чтение, поэтому нет опасности, что он действительно получит сообщение.
Не уверен, почему вы называете сон неприятным, это обходной путь, но он работает ... Нет ли способа проверить, содержит ли очередь jms сообщение в вашем вызове await (). AsMost ()?