Как отключить обработчик Spring SQS в тесте модуля / интеграции

У меня есть приложение для весенней загрузки, которое не более чем прослушивает очередь SQS через компонент «MessageHandler», у которого есть метод с аннотациями @ SqsListener, и начинает некоторую работу, когда приходит сообщение.

Также существует зависимость boot-starter-web, поскольку мы хотим получать статус работоспособности и метрики через http в производственной среде.

Теперь я хотел написать тест модуля, в котором уже есть контекст приложения и компоненты autowires. Я также узнал, как отключить веб-сервер, который не нужен тесту:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)

Однако bean-компонент MessageHandler также создается и пытается подключиться к AWS, чего я бы хотел предотвратить.

Одно из эффективных решений - иметь тестовую реализацию в src / test / java с аннотацией @Primary, чей метод handleMessage НЕ имеет аннотации @SqsListener:

@Component
@Primary
public class TestMessageHandler implements MessageHandler {

    @Override
    public void handleMessage(final NewMessage newMessage) throws Exception {
        return null;
    }
}

Но теперь я хотел бы также протестировать (настоящий) bean-компонент MessageHandler, то есть я бы хотел, чтобы Spring создал его экземпляр и автоматически связал его зависимости, но я все еще не хочу, чтобы аннотации @SqsListener становились активными, поэтому я могу вызвать в моем тесте это было так:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)
public class IntegrationTest {

    @Autowired
    private RealMessageHandler messageHandler;


    @Test
    public void testHandleMessage() throws Exception {
        messageHandler.handleMessage(new NewMessage(...));
    }
}

Итак, мне нужно отключить магию модуля spring-cloud-aws-starter, который устанавливает прослушиватель SQS для метода handleMessage в RealMessageHandler.

Есть какие-нибудь подсказки, как бы я это сделал?


person Bernhard    schedule 18.05.2017    source источник


Ответы (2)


У меня была аналогичная проблема, и я решил ее, высмеяв bean-компонент SimpleMessageListenerContainer. Я планирую сделать это для нескольких интеграционных тестов, чтобы эти тесты были более удобочитаемыми, я создал класс @TestConfiguration, который затем импортирую в тест.

Это мой класс конфигурации:


/**
 * Configuration class for integration test that do not need message listening capabilities.
 */
@TestConfiguration
public class MockMessageListenerConfiguration {

  @MockBean
  private SimpleMessageListenerContainer messageListenerContainer;

}

А я использую это так:

@SpringBootTest
@Import({MockMessageListenerConfiguration.class})
class BookingRepositoryIT {...}

После этого при отказе в соединении исчезли предупреждения, связанные с AWS SQS.

person Pim Hazebroek    schedule 19.09.2019
comment
Спасибо, что посмотрели на это. К сожалению, я больше не участвую в проекте, в котором у меня возникла эта проблема, и мне не удалось проверить это с помощью нового весеннего облачного проекта, потому что теперь он, похоже, работает из коробки. Поскольку я не могу это проверить, я не могу принять ваш ответ, но, возможно, кто-то еще может оставить отзыв, если это сработало для него. - person Bernhard; 06.02.2020
comment
Большое спасибо, вы меня спасли! - person Dmitry Adonin; 19.01.2021

Для тех, кто хочет протестировать приложение, не высмеивая фактический процесс отправки / получения очереди, вы можете сделать следующее.

В тестовой автосоединении шаблон сообщений затем отключите слушателей следующим образом:

@Autowired
private SimpleMessageListenerContainer simpleMessageListenerContainer;
@Autowired
private QueueMessagingTemplate queueMessagingTemplate;

@Test
public void test() {
String logicalQueueName = "my-queue";
simpleMessageListenerContainer.stop(logicalQueueName);
// code that will trigger message to be inserted into the queue

    Message<?> msg = ((QueueMessagingTemplate) queueMessagingTemplate)
        .receive(logicalQueueName);
// process msg
}

Имейте в виду, что слушатели не будут запускаться автоматически после этого, поэтому вы можете рассмотреть возможность использования аннотации DirtiesContext в своем тестовом классе.

person Borislav Stoilov    schedule 08.05.2020