Mock Apache Camel из локации в тестировании JUnit
Я пытаюсь издеваться in
а также out
пути верблюжьих маршрутов, но я не знаю, как обеспечить макет входного и выходного пути. Пожалуйста, помогите мне исправить это. Спасибо заранее.
application.properties
inputFilePath = src/main/resources/in
outputFilePath = src/main/resources/out
application-test.properties
inputFilePath = src/test/java/in
outputFilePath = src/test/java/out
Маршрутизатор и процессор:
@Component
public class FileLineByLineRouter extends RouteBuilder {
@Value("${inputFilePath}")
private String inputFilePath;
@Value("${outputFilePath}")
private String outputFilePath;
@Override
public void configure() throws Exception {
from("file://" + inputFilePath + "?delete=true").routeId("FileLineByLineRoute").marshal().string("UTF-8")
.split(body().tokenize("\n")).streaming().process(getFileParsingProcessor())
.to("file://" + outputFilePath + "?fileExist=Append").end();
}
@Bean
public Processor getFileParsingProcessor() {
return new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
String order = exchange.getIn().getBody(String.class);
order = order + ": " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss S").format(new Date()) + "\n";
exchange.getIn().setBody(order);
}
};
}
}
Код тестирования Junit:
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
@SpringBootTest(classes = FileLineByLineRouter.class)
@ActiveProfiles("test")
@EnableAutoConfiguration
public class FileLineByLineRouterTest2 extends CamelTestSupport {
@Autowired
protected CamelContext camelContext;
@Test
public void test() throws Exception {
camelContext.start();
Thread.sleep(2000);
File outDir = new File("src/test/java/out");
System.out.println(outDir.getAbsolutePath());
assertTrue(outDir.isDirectory());
assertTrue(outDir.listFiles().length != 0);
}
}
Журналы:
114 SpringCamelContext : Route: FileLineByLineRoute started and consuming from: file://src/test/java/in?delete=true
116 SpringCamelContext : Total 1 routes, of which 1 are started.
122 SpringCamelContext : Apache Camel 2.19.1 (CamelContext: camel-1) started in 0.582 seconds
138 FileLineByLineRouterTest2 : Started FileLineByLineRouterTest2 in 10.064 seconds (JVM running for 12.063)
179 FileLineByLineRouterTest2 : ********************************************************************************
180 FileLineByLineRouterTest2 : Testing: test(FileLineByLineRouterTest2)
180 FileLineByLineRouterTest2 : ********************************************************************************
222 o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.19.1 (CamelContext: camel-2) is starting
223 o.a.c.m.DefaultManagementStrategy : JMX is disabled
238 o.a.c.i.converter.DefaultTypeConverter : Loaded 193 type converters
239 o.apache.camel.impl.DefaultCamelContext : StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
239 o.apache.camel.impl.DefaultCamelContext : Total 0 routes, of which 0 are started.
239 o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.19.1 (CamelContext: camel-2) started in 0.017 seconds
239 SpringCamelContext : Apache Camel 2.19.1 (CamelContext: camel-1) is starting
239 SpringCamelContext : Total 1 routes, of which 1 are started.
239 SpringCamelContext : Apache Camel 2.19.1 (CamelContext: camel-1) started in 0.000 seconds
C:\Users\workspace\CamelProject\src\test\java\out
241 FileLineByLineRouterTest2 : ********************************************************************************
241 FileLineByLineRouterTest2 : Testing done: test(FileLineByLineRouterTest2)
241 FileLineByLineRouterTest2 : Took: 0.002 seconds (2 millis)
241 FileLineByLineRouterTest2 : ********************************************************************************
242 o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.19.1 (CamelContext: camel-2) is shutting down
314 o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.19.1 (CamelContext: camel-2) uptime 0.092 seconds
318 o.apache.camel.impl.DefaultCamelContext : Apache Camel 2.19.1 (CamelContext: camel-2) is shutdown in 0.071 seconds
336 o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@394df057: startup date [Mon Jan 08 17:32:43 IST 2018]; root of context hierarchy
344 o.a.camel.spring.SpringCamelContext : Apache Camel 2.19.1 (CamelContext: camel-1) is shutting down
346 o.a.camel.impl.DefaultShutdownStrategy : Starting to graceful shutdown 1 routes (timeout 300 seconds)
356 INFO 19900 --- [ - ShutdownTask] o.a.camel.impl.DefaultShutdownStrategy : Route: FileLineByLineRoute shutdown complete, was consuming from: file://src/test/java/in?delete=true
356 o.a.camel.impl.DefaultShutdownStrategy : Graceful shutdown of 1 routes completed in 0 seconds
362 o.a.camel.spring.SpringCamelContext : Apache Camel 2.19.1 (CamelContext: camel-1) uptime 0.123 seconds
362 o.a.camel.spring.SpringCamelContext : Apache Camel 2.19.1 (CamelContext: camel-1) is shutdown in 0.018 seconds
4 ответа
Хорошо, после перечитывания ваших комментариев и обновленного вопроса, я думаю, теперь я понимаю, что вы имеете в виду... ваш тест просто еще не работает.
Попробуй это:
- Удалить
extends CamelTestSupport
в вашем тестовом классе. Это альтернативный способ поддержки тестов на основе аннотаций. - Удалить
camelContext.start()
в вашем тесте. Я, вероятно, перепутал вас с моим примером совета. Вам нужно только начать контекст самостоятельно, когда вы аннотируете класс@UseAdviceWith
- И, наконец, просто подожди немного. Для примера вставьте
Thread.sleep(10000)
в вашем тесте, чтобы дать файлам время для обработки.
Вместо фиксированного сна вы можете использовать Camel NotifyBuilder ( http://camel.apache.org/notifybuilder.html)
Кажется, вы используете Camel в сочетании с Spring. Общая схема, которую я здесь использую, обычно ниже, которую я прокомментировал, чтобы объяснить, для чего нужна используемая концепция.
Обратите внимание, что я также добавил универсальный сервис, представленный как Spring bean, который фактически определяется как Mockito mock, чтобы продемонстрировать, как вы можете использовать такие mock в своем тесте.
// These 2 annotation allow the injection of Spring beans into this test class as
// well, ideally if you want to mock certain services defined as Spring bean
// with i.e. Mockito
@RunWith(CamelSpringRunner.class)
@BootstrapWith(CamelTestContextBootstrapper.class)
// we are going to slightly modify the route to test in order to simplify
// things a bit, hence we use @UseAdviceWith
@UseAdviceWith
@ContextConfiguration(loader = AnnotationConfigContextLoader.class,
classes = { FileLineByLineRouterTest2.ContextConfig.class })
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class FileLineByLineRouterTest2 {
// Spring bean setup needed to setup the beans required while testing your route
@Configuration
@PropertySource({"classpath:application-test.properties"})
public static class ContextConfig extends CamelConfiguration {
@Override
public List<RouteBuilder> routes() {
final List<RouteBuilder> routes = new ArrayList<>();
routes.add(routeToTest());
return routes;
}
// This bean is required to access the property files using @Value("${...}")
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public FileLineByLineRouter routeToTest() {
return new FileLineByLineRouter();
}
@Bean
public SomeService mockService() {
return mock(SomeService.class);
}
}
@Autowired
private CamelContext camelContext;
@Autowired
private ProducerTemplate template;
@Autowired
private SomeService someService;
// @MockEndpoints("mock:result")
// private MockEndpoint resultEndpoint
@Test
public void test() throws Exception {
// ARRANGE
// modify the route to test to simplify testing
camelContext.getRouteDefinition("FileLineByLineRoute")
.adviceWith((ModelCamelContext) camelContext,
new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
// replace the file endpoint used in the from RouteBuilder
// method with a direct endpoint for easier testing
this.replaceFromWith("direct:start");
// redirect the output which should be written to a file
// to a mock endpoint
this.interceptSendToEndpoint("file:*")
.skipSendToOriginalEndpoint()
.to("mock:result");
}
});
// create a mock endpoint to redirect output and define some basic assertions
// on either the number of processed outputs or the format of the body
// received by that mock endpoint. You can also use the commented out
// annotation approach from above instead
// More information available at: http://camel.apache.org/mock.html
MockEndpoint resultEndpoint = camelContext.getEndpoint("mock:result", MockEndpoint.class);
resultEndpoint.expectedMessageCount(1);
// other assertions on the mock endpoint possible as well here
// define behavior of mocks
when(someService.doSomething()).thenReturn("something");
// ACT
// use the producer template to send a body (and headers) to the route
// to test. This can litteraly be anything. A byte array, a simple string,
// a complex object, ...
String testContent = "...";
template.sendBody("direct:start", testContent);
// ASSERT
// check that the mock endpoint has received the actual number of bodies specified
// before invoking the template above
resultEndpoint.assertIsSatisfied();
// retrieve the final body and/or headers from the processed exchanges
// and perform your assertion against them
List<Exchange> exchanges = resultEndpoint.getExchanges();
assertThat(exchanges.size(), is(equalTo(1));
Object retBody = exchanges.get(1).getOut().getBody();
assertThat(retBody, is(equalTo(...));
}
}
Если вы хотите сохранить для проверки путь к потребителю и производителю файлов, я бы использовал JUnits TemporaryFolder
Правило, которое может выглядеть примерно так:
private MockEndpoint result;
@Rule
public TemporaryFolder sourceFolder = new TemporaryFolder();
@Before
public void init() throws Exception {
result = context.getEndpoint("mock:result", MockEndpoint.class);
context.getRouteDefinition("route-to-test")
.adviceWith((ModelCamelContext) context,
new AdviceWithRouteBuilder() {
@Override
public void configure() throws Exception {
replaceFromWith("file://" + sourceFolder.getRoot().toString()
+"?fileExist=Move"
+ "&moveExisting=${file:name.noext}-${date:now:yyyyMMddHHmmssSSS}.${file:ext}"
+ "&tempFileName=${file:name}.tmp");
interceptSendToEndpoint("file:*").skipSendToOriginalEndpoint().to(result);
}
});
writeFileContent("sample1.xml", "/filesystem/outbound/sample1.xml");
writeFileContent("sample2.xml", "/filesystem/outbound/sample2.xml");
writeFileContent("sample3.xml", "/filesystem/outbound/sample3.xml");
writeFileContent("sample4.xml", "/filesystem/outbound/sample4.xml");
context.start();
}
где writeFileContent
простые копии содержимого файла во временную папку, используемую для тестирования
private void writeFileContent(String name, String source) throws Exception {
File sample = sourceFolder.newFile(name);
byte[] bytes = IOUtils.toByteArray(getClass().getResourceAsStream(source));
FileUtils.writeByteArrayToFile(sample, bytes);
}
Вывод может быть фактически записан во временный тестовый каталог вместо обработки его через фиктивную конечную точку. Этот подход аналогичен определению временной тестовой директории для отправки файлов на маршрут. Поэтому я оставляю такой подход к вам.
Я думаю, что вы можете найти свой ответ здесь: образец FilterTest.java
Вот соответствующая выдержка.
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
public void configure() {
from("direct:start").filter(header("foo").isEqualTo("bar"))
.to("mock:result");
}
};
}
Вы можете извлечь in
а также out
пути к application-dev.properties (или yml).
path.in=src/main/resources/in
path.out=src/main/resources/out
Тогда configure()
метод должен измениться на что-то подобное
@Override
public void configure() throws Exception {
from("file://{{path.in}}?delete=true")
.routeId("FileLineByLineRoute")
.marshal().string("UTF-8")
.split(body().tokenize("\n")).streaming()
.process(getFileParsingProcessor())
.to("file://{{path.out}}?fileExist=Append")
.end();
}
Затем в ваших тестах вы можете смоделировать свойства или загрузить другой файл свойств.