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() { [...] });
我強烈推薦這種方法,它可以節省大量時間來確定測試失敗的原因