Tiven Wang
Wang Tiven December 15, 2017
425 favorite favorites
bookmark bookmark
share share

Mock ProducerTemplate

Testing is a crucial activity in any piece of software development or integration. Typically Camel Riders use various different technologies wired together in a variety of patterns with different expression languages together with different forms of Bean Integration and Dependency Injection so its very easy for things to go wrong! (smile) . Testing is the crucial weapon to ensure that things work as you would expect.

Camel is a Java library so you can easily wire up tests in whatever unit testing framework you use (JUnit 3.x (deprecated), 4.x, or TestNG). However the Camel project has tried to make the testing of Camel as easy and powerful as possible so we have introduced the following features.

We can use Spring for IoC and the Camel Mock and Test endpoints to create sophisticated integration/unit tests that are easy to run and debug inside your IDE. There are three supported approaches for testing with Spring in Camel.

本文所演示项目代码是基于另一文章Spring Boot - Apache Camel介绍了 Spring Boot 程序里运行 Apache Camel 的基本架构,其代码下载 Github

Testing Dependencies

camel-test-spring 提供了 Camel 和 Spring 结合使用的测试方法。spring-boot-starter-test 提供了 Spring 基本测试框架。

<!-- Testing -->
<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-test-spring</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

Unit Test

Using the org.apache.camel.test.spring.CamelSpringBootRunner runner with the @RunWith annotation or extending org.apache.camel.testng.AbstractCamelTestNGSpringContextTests provides the full feature set of Spring Test with support for the feature set provided in the CamelTestSupport classes.

import org.apache.camel.test.spring.CamelSpringBootRunner;
import org.springframework.boot.test.context.SpringBootTest;

@RunWith(CamelSpringBootRunner.class)
@SpringBootTest
public class StarterApplicationTests {
  ...
}

因为之前的代码是 Camel 创建 Restful API 的 Route,那么要测试的话就需要调用 Rest endpoint。这里还可以通过 Camel 的 direct:[endpoint] 来测试。修改一下代码,把原来的 Rest route 断开,新增一个 direct 端点:

rest("/books").description("Books REST service")
  .get("/").description("The list of all the books")
      .route().routeId("books-api")
      .inOut("direct:books")              
      .endRest()
  .get("/{id}").description("Details of an book by id")
      .route().routeId("book-api")
      .inOut("direct:book");

from("direct:books").bean("bookRepository", "getAll");
from("direct:book").bean("bookRepository", "getByIsbn(${header.id})");

这个就可以对 direct:booksdirect:book 进行独立测试,下面是对 book route 的测试代码

@Test
public void testBook() {

	Exchange exchange = new DefaultExchange(camelContext);
	Message in = new DefaultMessage(camelContext);
	in.setHeader("id", 123);
	exchange.setIn(in);
	exchange = camelContext.createProducerTemplate().send("direct:book", exchange);
	Message message = exchange.getIn();
	assertEquals("123", ((Book) message.getBody()).getIsbn());
}

截至此步骤完整代码 Github

Endpoint Inject

除了使用 CamelContext 创建 ProducerTemplate 外还可以通过注解 @EndpointInject 来自动注入特定的 ProducerTemplate 对象或者 MockEndpoint 对象。

@EndpointInject(uri = "direct:book")
private ProducerTemplate book;

@EndpointInject(uri = "mock:result")     
protected MockEndpoint result;

@Test
public void testBook() throws InterruptedException {
  ...
  result.expectedMessageCount(1);

  exchange = book.send(exchange);

  result.assertIsSatisfied();
}

Simulate Errors

本篇完整代码 Github

Similar Posts

Comments

Back to Top