Camel Integration 測試類示例

不要忘記將 camel 測試支援和 spring camel 測試支援新增到專案依賴項中。有關 maven 使用者,請參閱以下內容:

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-test</artifactId>
  <version>${camel.version}</version>
  <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test-spring</artifactId>
    <version>${camel.version}</version>
     <scope>test</scope>
</dependency>

該類將在示例路由上觸發並執行測試。這些測試還使用 DBUnit 來模擬資料庫,儘管你可以配置上下文以使用真實或其他型別的模擬資料庫。

首先,我們使用抽象類來共享我們稍後將使用的每個 Camel Integration Test 類之間的共同註釋:

@RunWith(CamelSpringRunner.class)
@BootstrapWith(CamelTestContextBootstrapper.class)
@ContextConfiguration(locations = { "classpath:/test-beans.xml" })
@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
        DbUnitTestExecutionListener.class })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public abstract class AbstractCamelTI {

}

**小心不要忘記任何註釋,**否則你的 DAO 將無法正確注入。話雖這麼說,如果你不想使用上下文配置中描述的資料庫,你可以安全地刪除 DBUnit 註釋。

重要編輯 :我最近新增了 @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)。這樣,每次測試都會重新載入 camel 上下文。你可以單獨測試路線的每個部分。但是,如果你真的想要這樣,你需要在你不想要的所選路線的部分上使用 remove() 。有些人會認為這不是一個真正的整合測試,他們是對的。但是,如果像我一樣,你需要重構大型處理器,你可以從那裡開始。

下面的程式碼描述了測試類的開始(參見下面的實際測試):

@DatabaseSetup(value = { "/db_data/dao/common.xml", "/db_data/dao/importDocumentDAOCommonTest.xml" })
public class TestExampleProcessorTest extends AbstractCamelTI {

    @Autowired
    protected CamelContext camelContext;

    @EndpointInject(uri = "mock:catchTestEndpoint")
    protected MockEndpoint mockEndpoint;

    @Produce(uri = TestExampleRoute.ENDPOINT_EXAMPLE)
    protected ProducerTemplate template;

    @Autowired
    ImportDocumentTraitementDAO importDocumentTraitementDAO;

    // -- Variables for tests
    ImportDocumentProcess importDocumentProcess;

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();

        importDocumentProcess = new ImportDocumentProcess();
        //specific implementation of your choice
    }
}

以下測試應該觸發路由的第一部分並將其引導至 mockEndpoint,以便我們可以測試是否已正確選擇 ImportDocumentProcess 並將其放入標題中:

@Test
public void processCorrectlyObtained_getImportDocumentProcess() throws Exception {
    camelContext.getRouteDefinitions().get(0).adviceWith(camelContext, new AdviceWithRouteBuilder() {

        @Override
        public void configure() throws Exception {
            weaveById("getImportDocumentProcess").after().to(mockEndpoint);
        }
    });

    // -- Launching the route
    camelContext.start();
    template.sendBodyAndHeader(null, "entreprise", company);

    mockEndpoint.expectedMessageCount(1);
    mockEndpoint.expectedHeaderReceived(TestExampleProcessor.HEADER_UTILISATEUR, null);
    mockEndpoint.expectedHeaderReceived(TestExampleProcessor.HEADER_IMPORTDOCPROCESS, importDocumentProcess);
    mockEndpoint.assertIsSatisfied();

    camelContext.stop();
}

最後一次測試觸發整個路線:

@Test
public void traitementCorrectlyCreated_createImportDocumentTraitement() throws Exception {
    camelContext.getRouteDefinitions().get(0).adviceWith(camelContext, new AdviceWithRouteBuilder() {

        @Override
        public void configure() throws Exception {
            weaveById("createImportDocumentTraitement").after().to(mockEndpoint);
        }
    });

    // -- Launching the route
    camelContext.start();

    Exchange exchange = new DefaultExchange(camelContext);
    exchange.getIn().setHeader(TestExampleProcessor.HEADER_ENTREPRISE, company);
    exchange.getIn().setHeader(TestExampleProcessor.HEADER_UTILISATEUR, null); // No user in this case
    exchange.getIn().setHeader(TestExampleProcessor.HEADER_IMPORTDOCPROCESS, importDocumentProcess);

    long numberOfTraitementBefore = this.importDocumentTraitementDAO.countNumberOfImportDocumentTraitement();

    template.send(exchange);

    mockEndpoint.expectedMessageCount(1);
    mockEndpoint.assertIsSatisfied();

    camelContext.stop();

    long numberOfTraitementAfter = this.importDocumentTraitementDAO.countNumberOfImportDocumentTraitement();
    assertEquals(numberOfTraitementBefore + 1L, numberOfTraitementAfter);
}

也可以將當前路由重定向到另一個程序。但我更喜歡重定向到 mockEndpoint。它更有趣,因為你可以真正對你的交換體和標題進行中間測試。

重要說明 :在此示例中,我使用以下程式碼來獲取路由並在其上使用 adviceWith

camelContext.getRouteDefinitions().get(0).adviceWith(camelContext, new AdviceWithRouteBuilder() { [...] });

然而,可以通過先前定義為字串的 ID 來獲取路由,如下所示:

 camelContext.getRouteDefinition("routeId").adviceWith(camelContext, new AdviceWithRouteBuilder() {  [...]  });

我強烈推薦這種方法,它可以節省大量時間來確定測試失敗的原因