簡體   English   中英

在JUnit測試中模擬Apache Camel的位置

[英]Mock Apache Camel out location in JUnit testing

我試圖嘲弄inout駱駝路線的路徑,但我不知道如何進出path.Please幫我解決this.Thanks提前提供模擬。

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

似乎您將Camel與Spring結合使用。 我在這里使用的一般設置通常是下面的內容,下面我將對其進行評論以解釋所使用的概念有什么用處。

請注意,我還添加了一個作為Spring bean公開的通用服務,該服務實際上定義為Mockito模擬,以展示如何在測試中利用此類模擬。

// 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);
}

實際上,也可以將輸出寫入臨時測試目錄,而不用通過模擬端點對其進行處理。 然后,此方法類似於定義用於將文件發送到路由的臨時測試目錄。 因此,我將這種方法留給您。

好的,在重新閱讀您的評論和更新的問題之后,我想我現在已經明白了您的意思了……您的測試還無法進行。

嘗試這個:

  • 刪除您的Testclass中的CamelTestSupport extends CamelTestSupport 這是基於注釋的測試支持的替代方法。
  • 在測試中刪除camelContext.start() 我可能將我的建議示例弄糊塗了。 使用@UseAdviceWith注釋類時,僅需要自己啟動上下文。
  • 最后,請稍等。 為了便於說明,請在測試中插入Thread.sleep(10000) ,以使文件有時間進行處理。

您可以使用Camel NotifyBuilder( http://camel.apache.org/notifybuilder.html )來代替固定睡眠。

您可以提取到application-dev.properties(或yml)的inout路徑。

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();
}

然后在測試中,您可以模擬屬性,也可以加載其他屬性文件

我認為您可能會在這里找到答案: 示例FilterTest.java

這是相關的摘錄。

@Override
protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
          from("direct:start").filter(header("foo").isEqualTo("bar"))
          .to("mock:result");
        }
    };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM