在专家的帮助下,在有问题的骆驼单元测试与 cametestsupport 的帮助下,模板总是为空,我最终又遇到了一个问题。
下面是我的测试类 - 一个简单的测试,测试只有ValidationProcessor POJO的路由。
public class RouteTests extends CamelTestSupport {
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
from("direct:start")
.filter().method(ValidationProcessor.class, "validate")
.to("mock:result");
}
};
}
@Test
public void testSendMatchingMessage() throws Exception {
ObjectMapper objectmapper = new ObjectMapper();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("test.json");
JSONObject testJson = new JSONObject(objectmapper.readValue(stream, Map.class));
MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
resultEndpoint.expectedMessageCount(1);
template.sendBody("direct:start", testJson);
resultEndpoint.assertIsSatisfied();
}
}
当这个验证处理器中有一个@Autowired
组件时,问题就来了。我的验证方法需要来自 Elasticsearch 的数据,因此我有一个弹性客户端@Autowired
。
当我运行 mvn clean test
时,我收到一条NullPointerException
,指出此弹性客户端为 null。我认为问题是这个测试与 Spring 没有任何关系,因此这个问题,但我不知道如何克服这一点。
我的测试需要从Elasticsearch获取数据,因此ValidationProcessor POJO确实需要@Autowired
。
当你扩展CamelTestSupport
时,它就不是一个 Spring 应用程序。您需要扩展CamelSpringTestSupport
.这将在 Spring 运行时中创建 Camel,然后允许 bean 通过 Spring 获得 IoC。这种测试通常用于 Camel XML 路由,其中路由在 XML 文件中定义。但是,您可以拥有一个纯XML文件,也可以引用Java DSL中的路由。
然而,正如Makoto所回答的那样,香草Spring单元测试最近经常是关于使用所有这些无数的注释。骆驼对此表示支持,他的回答也表明了这一点。这也是例如 Spring 启动测试等方式。
您可以在camel-test-spring
中找到一些单元测试,也可以用作灵感。
我发现,当你想在 Spring 中使用任何东西时,扩展CamelTestSupport
是不明智的。 事实上,有一个更好的方法 - 改用CamelSpringBootRunner
。
井。。。我说"更好"。 你会发现自己附加了大量的注释。 在您需要的物品中:
- 一个增强器,以确保您正确引导骆驼
- 您希望添加到类路径(以及所有 bean(的路由;这可确保它们通过 Spring 的注册表添加到 Camel 的注册表中
- 您必须在每次运行后弄脏上下文,否则您的测试就会进入不稳定状态。
- 您可以通过指定
@MockEndpoints
或@MockEndpointsAndSkip
来自动模拟端点。 前者将数据发送到实际路由。
下面只是一个开始。 其中许多注释及其文档可以在正式文档中找到。
@RunWith(CamelSpringBootRunner.class)
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@ActiveProfiles("test")
@SpringBootTest(classes = { YourEntryPointClass.class })
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@UseAdviceWith
@MockEndpoints("direct:*")
public class RouteTests {
}