Я пытаюсь написать модульные тесты для маршрута верблюда - его для импорта и обработки файла
from(fullImportFTP)
.routeId(STUB_FILE_DOWNLOAD_ROUTE_ID)
.onException(Exception.class)
.handled(false)
.log(LoggingLevel.ERROR, STUB_IMPORT_ERROR_CODE)
.end()
.log("Processing Stub file:[${header.CamelFileName}]")
.to(ROUTE_TO_MACE);
from(ROUTE_TO_MACE)
.routeId(STUB_FILE_IMPORT_ROUTE_ID)
.onException(Exception.class)
.handled(false)
.log(LoggingLevel.ERROR, STUB_IMPORT_ERROR_CODE)
.end()
.onException(IOException.class)
.maximumRedeliveries(routesConfig.camelMaximumRetries).redeliveryDelay(routesConfig.camelRedeliveryDelay)
.handled(false)
.log(LoggingLevel.ERROR, STUB_IMPORT_ERROR_CODE)
.end()
.split().tokenizeXML(ITEM).streaming()
.process(processor)
.to("log:route.StubRoute?level=DEBUG")
.end()
.log("Stub file sucessfully processed:[${header.CamelFileName}]");
И ниже модульный тест:
@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CamelRouteTest {
@EndpointInject(uri = "mock:success_result")
private MockEndpoint successResultEndpoint;
@EndpointInject(uri = "direct:mock-import-stub-download")
private FluentProducerTemplate producer;
@Autowired
private CamelContext camelContext;
@MockBean
RestTemplate restTemplate;
private static final String MOCK_IMPORT_STUB_DOWNLOAD = "direct:mock-import-stub-download";
private static final String TEST_STUB_FILE_LOCATION = "src/test/resources";
@Before
public void setup() throws Exception {
camelContext.getRouteDefinition(STUB_FILE_DOWNLOAD_ROUTE_ID).autoStartup(true).adviceWith(camelContext,
new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
replaceFromWith(MOCK_IMPORT_STUB_DOWNLOAD);
interceptSendToEndpoint("log:route.StubRoute?level=DEBUG").skipSendToOriginalEndpoint().to(successResultEndpoint);
}
});
camelContext.start();
}
@Test
public void testFileDownloadRouter() throws Exception {
File file = new File(TEST_STUB_FILE_LOCATION + "/Stub_11092018_162149_59642501.xml");
successResultEndpoint.expectedMessageCount(1);
producer.withBody(file).withHeader(Exchange.FILE_NAME, "Stub_24102018_162149_59642501.xml").send();
successResultEndpoint.assertIsSatisfied();
}
Я всегда получаю счетчик сообщений как 0. Вот ОШИБКА.
java.lang.AssertionError: mock://success_result Received message count. Expected: <1> but was: <0> Expected :<1> Actual :<0>
Что я здесь делаю не так? У меня есть 2 маршрута, как вы можете видеть - первый фактически идет ко второму, поэтому в модульных тестах я тоже должен иметь 2 маршрута? Я не добавил 2 маршрута, потому что, если я отлаживаю, я вижу, что он действительно проходит через процессор и возвращает правильный результат.




Прежде всего: вы используете AdviceWith, поэтому вам следует поместить аннотацию @UseAdviceWith в свой тестовый класс. В противном случае автоматический запуск контекста Camel и рекомендации по маршруту могут перекрываться.
Для отсутствующего сообщения в Mock: Возможно, ваш тест просто утверждает слишком рано. Я предполагаю, что производитель не блокирует, пока сообщение обрабатывается, но утверждение MockEndpoint следует сразу после отправки сообщения. Сразу после отправки сообщения количество полученных сообщений по-прежнему равно 0.
Чтобы проверить, помогает ли ожидание, вы можете вставить Thread.sleep (). Если он работает, вы должны избавьтесь от Thread.sleep () и заменить его на Camel NotifyBuilder
Просто увидел еще один момент. Последний to() в вашей цепочке interceptSendToEndpoint указывает на переменную экземпляра MockEndpoint. Я думаю, это должно указывать на URI MockEndpoint, то есть .to("mock:success_result")
И даже еще одно: вы получаете первый путь к совету с getRouteDefinition(STUB_FILE_DOWNLOAD_ROUTE_ID), но в этом блоке советов вы получаете совет оба маршрута. Вероятно, в этом причина вашей проблемы. Второй путь не рекомендуется, и поэтому ваш макет не подходит. Вы должны указать второй маршрут в отдельном блоке рекомендаций.
@Before
public void setup() throws Exception {
camelContext.getRouteDefinition(STUB_FILE_DOWNLOAD_ROUTE_ID).autoStartup(true).adviceWith(camelContext, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
replaceFromWith(MOCK_IMPORT_STUB_DOWNLOAD);
}
});
camelContext.getRouteDefinition(STUB_FILE_IMPORT_ROUTE_ID).autoStartup(true).adviceWith(camelContext, new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
interceptSendToEndpoint("log:route.StubRoute?level=DEBUG").skipSendToOriginalEndpoint().to("mock:success_result");
}
});
camelContext.start();
}
также изменил interceptEndPoint на URI, снова не работает .. Не знаю, пригодится ли это, но я вижу это в журналах - "camel.component.mock.MockEndpoint: Asserting: mock: // success_result isisfied" перед отключением маршрутов и сообщением об ошибке.
Да, это регистрируется при проверке утверждения. Это не означает, что он удовлетворен, это похоже на «Утверждение сейчас, если фиктивный удовлетворен ...», и тогда результатом является сообщение об ошибке.
Просто чтобы изолировать проблему. Можете ли вы статически заменить лог-оператор на фиктивную конечную точку, т.е. изменить код так, как должен поступать перехватчик, и отключить перехватчик? Если это сработает, значит, проблема с перехватчиком. Если он по-прежнему не работает, то конечная точка Mock работает некорректно.
Только что видел еще один: ваш блок рекомендаций ссылается на первый маршрут. Поэтому второй маршрут не рекомендуется, и ваша фиктивная конечная точка не на своем месте.
как это сделать? я должен иметь 2 ссылки?
Вы должны сделать два отдельных совета с блоками, см. В моем расширенном ответе
Я добавил аннотацию @UseAdviceWith и отложил ожидание, но, к сожалению, это все равно не удается ..