使用 Blueprint XML 和 Java Bean 的 Apache Camel 3.14.7 路由单元测试出现问题

问题描述 投票:0回答:1

我正在使用 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 的特定需求?

apache-camel osgi apache-karaf
1个回答
0
投票

在对骆驼路由进行单元测试时,您可以使用 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
功能轻松创建临时数据库进行测试。

© www.soinside.com 2019 - 2024. All rights reserved.