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() { [...] });
我强烈推荐这种方法,它可以节省大量时间来确定测试失败的原因