В приложении Apache Camel как модульные тесты могут вводить фиктивные конечные точки вместо реальных?
Я реализуюшаблон переводчика сообщений с помощью Apache Camel - принимать сообщения от конечной точки RESTful и отправлять их в конечную точку AMQP.
Вложенное приложение основано на Spring Boot, и поэтому я использую Camel's "весна-загрузкакомпонент для интеграции двух платформ. Как указано в документации по этой ссылке при загрузке, я реализую свой верблюжий маршрут внутри@Configuration
-аннотированный класс, который расширяетсяRouteBuilder
:
@Component
public class MyRestToAmqpRouter extends RouteBuilder {
@Override
public void configure() throws Exception {
from("jetty:http://my-restful-url")
.process(exchange -> {
// convert the message body from JSON to XML, take some
// incoming header values and put them in the outgoing
// body, etc...
}).to("rabbitmq://my-rabbitmq-url");
}
}
Мой вопрос состоит в том, как выполнить модульное тестирование этого перевода, не нуждаясь в реальной конечной точке RESTful или настроенном брокере RabbitMQ? Я прочитал много примеров в Интернете, а такжеВерблюд в действии книга ... и кажется, что типичный подход для модульного тестирования маршрута Camel состоит в том, чтобы вырезать и вставить маршрут в свой модульный тест и заменить один или несколько URL-адресов конечных точек на "mock:whatever
».
я думаю чтоСорта работает ... но это ужасно хрупко, и ваш набор тестов не распознает, когда кто-то позже изменит реальный код без обновления модульного теста.
Я попытался адаптировать некоторые примеры модульного тестирования на основе Spring с помощью макетов, например:
@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Application.class})
public class MyRestToAmqpRouterTest extends AbstractJUnit4SpringContextTests {
@Produce(uri = "jetty:http://my-restful-url")
private ProducerTemplate fakeRest;
@EndpointInject(uri = "rabbitmq://my-rabbit-url")
private MockEndpoint fakeRabbit;
@Test
@DirtiesContext
public void testRouter() throws InterruptedException {
fakeRabbit.expectedMessageCount(1);
fakeRest.sendBodyAndHeader("", "header-1", "some value");
fakeRabbit.assertIsSatisfied();
}
}
Я надеялся, что Camel возьмет эти URL-адреса конечных точек из модульного теста, зарегистрирует их как ложные ... и затем будет использовать mocks, а не реальную конечную точку, когда реальный код пытается использовать эти URL-адреса.
Однако я не уверен, что это возможно. Когда я использую реальные URL-адреса в модульном тесте, я получаюIllegalArgumentException
потому что вы, очевидно, не можете ввести «реальный» URL конечной точки вMockEndpoint
экземпляр (только URL с префиксом "mock:
«).
Когда я использую "mock:...
"URL-адрес конечной точки в моем модульном тесте, тогда он бесполезен, потому что ничто не связывает его с реальным URL-адресом конечной точки в тестируемом классе. Так что реальный URL-адрес конечной точки никогда не переопределяется. Когда выполняется реальный код, он просто использует реальную конечную точку как нормальный (и цель состоит в том, чтобы иметь возможность проводить тестирование без внешней зависимости от RabbitMQ).
Я что-то упускаю на действительно фундаментальном уровне здесь? Кажется, что для модульных тестов был бы способ внедрить поддельные маршруты в такой класс, чтобы тестируемый код мог переключаться с реальных конечных точек на фиктивные, даже не осознавая этого. В качестве альтернативы, я полагаю, что я мог бы реорганизовать свой код так, чтобы анонимныйProcessor
были повышены до автономного класса ... и тогда я мог тестировать его логику перевода независимо от маршрута. Но это только кажется неполным тестом.