我正在使用 Apache Camel 3.14.7 开发一个项目,结合 Blueprint XML 和 Java bean 进行路由定义。我面临着对这些路由进行单元测试的问题,它们涉及复杂的操作,例如数据库交互和 bean 处理。我尝试使用 CamelBlueprintTestSupport 进行测试,但我始终遇到空上下文问题,导致此方法无效。我的猜测是,这可能是由于 CamelBlueprintTestSupport 已过时,因为它似乎面向 Camel 版本 3.1.0。我注意到camel-test-infra 针对的是 3.16 及更高版本,可能会为我的版本留下一个空白。
考虑到我的路线涉及的复杂性,其中包括数据库调用、bean 方法调用和自定义处理器,我正在寻找一种支持完整 Blueprint XML 路线测试而不涉及 Spring 的测试策略。
这是我的上下文路线的示例片段:
<camelContext id="stFA" xmlns="http://camel.apache.org/schema/blueprint">
<route id="rStr">
<from uri="servlet://...."/>
<to uri="sql-stored:dbo.sp....."/>
<bean ref="fabO" method="transformTo(${body})" />
<to uri="sql:insert into..."/>
<process ref="formatJsonObjectsToJsonArrays"/>
</route>
这条路线没有意义,只是为了完整。
是否有已知的测试方法或解决方法可以满足带有 Blueprint XML 路由的 Apache Camel 3.14.7 的特定需求?
在对骆驼路由进行单元测试时,您可以使用 advicewith 用简单的模拟响应替换路由上的任何
camel-sql
或 camel-jdbc
端点。查询通常返回 List<Map<String, Object>>
或 List<outputClass>
类型的正文,更新返回 null。
List<ExampleModel> mockQueryResponse = createExampleResponseForTest();
AdviceWith.adviceWith(context, "exampleRoute", a -> {
a.weaveByToUri("sql:*")
.replace()
.setHeader(SqlConstants.SQL_ROW_COUNT).constant(mockQueryResponse.size())
.setBody().constant(mockQueryResponse)
;
});
使用adviceWith时,请记住重写is
isUseAdviceWith
方法以返回true并在template.send
调用之前手动启动路由
@Override
public boolean isUseAdviceWith() {
return true;
}
现在,由于许多蓝图经常引用 OSGi 服务,您可能必须模拟这些服务才能使 CamelBlueprintTestSupport 正常工作。这可以通过重写
addServicesOnStartup
方法之一来完成。
使用 Mockito 模拟框架模拟 OSGi JMS 和 DataSource 服务的示例。
@Override
protected void addServicesOnStartup(Map<String, KeyValueHolder<Object, Dictionary>> services) {
Properties mockArtemisProperties = new Properties();
mockArtemisProperties.put("name", "artemis");
services.put(ConnectionFactory.class.getCanonicalName(),
asService(mock(ConnectionFactory.class), mockArtemisProperties));
Properties mockDatasourceProperties = new Properties();
mockDatasourceProperties.put("dataSourceName", "exampleDatabase");
services.put(ConnectionFactory.class.getCanonicalName(),
asService(mock(DataSource.class), mockDatasourceProperties));
super.addServicesOnStartup(services);
}
模拟数据库响应将意味着 sql 查询将不再针对真实数据库进行测试。不过,我通常会认为像
camel-test-infra
这样的东西超出了单元和集成测试的范围。
如果您使用的是 sqlite 或 H2 等轻量级数据库,您可以使用 Junits
@TempDir
功能轻松创建临时数据库进行测试。