搜索

第 9 章 使用 JUnit 测试路由

download PDF

本教程介绍了如何使用 New Camel Test Case 向导来为路由创建测试案例,然后测试路由。

概述

New Camel Test Case 向导会生成一个 boilerplate JUnit 测试案例。当您创建或修改路由(例如,向它添加更多处理器)时,您应该创建或修改生成的测试案例,以添加特定于您创建或更新的路由的预期和断言。这样可确保测试对路由有效。

目标

在本教程中,您将完成以下任务:

  • 创建 /src/test/ 文件夹以存储 JUnit 测试案例
  • ZooOrderApp 项目生成 JUnit 测试案例
  • 修改新生成的 JUnit 测试案例
  • 修改 ZooOrderApp 项目的 pom.xml 文件
  • 使用新的 JUnit 测试案例运行 ZooOrderApp
  • 观察输出

先决条件

  1. 要启动本教程,您需要从以下之一生成的 ZooOrderApp 项目:

  2. Project Explorer 中的 ZooOrderApp 项目的 /src/data/ 目录和 /target/messages/ 子目录中删除任何 trace 生成的消息。trace 生成的消息以 ID- 前缀开头。例如: 图 9.1 “trace 生成的消息” 显示八个追踪生成的信息:

    图 9.1. trace 生成的消息

    tutTraceGenMsgs

    选择批处理中的所有 trace-generated 消息,右键单击并选择 Delete

创建 src/test 文件夹

在为 ZooOrderApp 项目创建 JUnit 测试案例前,您必须为构建路径中包含的文件夹创建一个文件夹:

  1. Project Explorer 中,右键单击 ZooOrderApp 项目,然后选择 New Folder
  2. New Folder 对话框中,在项目树窗格中展开 ZooOrderApp 节点,再选择 src 文件夹。

    确保 ZooOrderApp/src 出现在 Enter 或选择父文件夹 字段中。

  3. Folder name 中,输入 /test/java

    tutCreateJUnitTestFolder
  4. Finish

    Project Explorer 中,新的 src/test/java 文件夹显示在 src/main/resources 文件夹下:

    tutTestFolderAdded
  5. 验证新的 /src/test/java 文件夹是否包含在构建路径中。

    1. Project Explorer 中,右键单击 /src/test/java 文件夹,以打开上下文菜单。
    2. 选择 Build Path 来查看菜单选项:

      menu 选项 Remove from Build Path 验证 /src/test/java 文件夹目前是否包含在构建路径中:

      tutJavaFolderOnBldPath

创建 JUnit 测试案例

ZooOrderApp 项目创建 JUnit 测试案例:

  1. Project Explorer 中,选择 src/test/java
  2. 右键,然后选择 New Camel Test Case

    NewCamTstCaseTut
  3. Camel JUnit Test Case 向导中,确保 Source folder 字段包含 ZooOrderApp/src/test/java。要找到正确的文件夹,请点击 browse button
  4. Package 字段中,输入 tutorial.zooapp.route。此软件包将包括新的测试案例。
  5. test 字段中的 Camel XML 文件中,点 browse button 打开配置为过滤 XML 文件的文件管理器,然后选择 ZooOrderApp 项目的 blueprint.xml 文件:

    tutCamXMLUnderTst
  6. 点击 确定Name 字段默认为 BlueprintXmlTest

    tutCamJUnitTstPgComplete
  7. Next 以打开 Test Endpoints 页面。

    默认情况下,会选择所有端点,并将包含在测试案例中。

  8. Finish

    注意

    若有提示,请将 JUnit 添加到构建路径中。

测试的工件添加到项目中,并出现在 src/test/java 下的 Project Explorer 中。实施测试案例的类在工具的 Java 编辑器中打开:

package tutorial.zooapp.route;

import org.apache.camel.EndpointInject;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
import org.junit.Test;

public class BlueprintXmlTest extends CamelBlueprintTestSupport {

	// TODO Create test message bodies that work for the route(s) being tested
	// Expected message bodies
	protected Object[] expectedBodies = { "<something id='1'>expectedBody1</something>",
			"<something id='2'>expectedBody2</something>" };
	// Templates to send to input endpoints
	@Produce(uri = "file:src/data?noop=true")
	protected ProducerTemplate inputEndpoint;
	@Produce(uri = "direct:OrderFulfillment")
	protected ProducerTemplate input2Endpoint;
	// Mock endpoints used to consume messages from the output endpoints and then perform assertions
	@EndpointInject(uri = "mock:output")
	protected MockEndpoint outputEndpoint;
	@EndpointInject(uri = "mock:output2")
	protected MockEndpoint output2Endpoint;
	@EndpointInject(uri = "mock:output3")
	protected MockEndpoint output3Endpoint;
	@EndpointInject(uri = "mock:output4")
	protected MockEndpoint output4Endpoint;

	@Test
	public void testCamelRoute() throws Exception {
		// Create routes from the output endpoints to our mock endpoints so we can assert expectations
		context.addRoutes(new RouteBuilder() {
			@Override
			public void configure() throws Exception {
				from("file:target/messages/invalidOrders").to(outputEndpoint);
				from("file:target/messages/validOrders/USA").to(output3Endpoint);
				from("file:target/messages/validOrders/Germany").to(output4Endpoint);
			}
		});

		// Define some expectations

		// TODO Ensure expectations make sense for the route(s) we're testing
		outputEndpoint.expectedBodiesReceivedInAnyOrder(expectedBodies);

		// Send some messages to input endpoints
		for (Object expectedBody : expectedBodies) {
			inputEndpoint.sendBody(expectedBody);
		}

		// Validate our expectations
		assertMockEndpointsSatisfied();
	}

	@Override
	protected String getBlueprintDescriptor() {
		return "OSGI-INF/blueprint/blueprint.xml";
	}

}

对于 ZooOrderApp 项目,这个生成的 JUnit 测试案例不足,它将无法成功运行。您需要修改它以及项目的 pom.xml,如 “修改 BlueprintXmlTest 文件”一节“修改 pom.xml 文件”一节 所述。

修改 BlueprintXmlTest 文件

您必须将 BlueprintXmlTest.java 文件修改为:

  • 导入多个支持所需文件功能的类
  • 创建用于保存各种源 .xml 文件的内容的变量
  • 读取源 .xml 文件的内容
  • 定义适当的预期

按照以下步骤修改 BlueprintXmlTest.java 文件:

  1. Project Explorer 中,展开 ZooOrderApp 项目,以公开 BlueprintXmlTest.java 文件:

    tutBlueprintXMLTestProjExp
  2. 打开 BlueprintXmlTest.java 文件。
  3. 在 Java 编辑器中,单击 导入 org.apache.camel.EndpointInject; 旁边的展开按钮,以展开该列表。
  4. 添加以粗体文本显示的两行。根据下一部分的指示,添加第一行会导致当您更新 pom.xml 文件时解析的错误。

    package tutorial.zooapp.route;
    
    import org.apache.camel.EndpointInject;
    import org.apache.camel.Produce;
    import org.apache.camel.ProducerTemplate;
    import org.apache.camel.builder.RouteBuilder;
    import org.apache.camel.component.mock.MockEndpoint;
    import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
    import org.apache.commons.io.FileUtils;
    import org.junit.Test;
    import java.io.File;
  5. 向下滚动到直接在 // 预期消息正文后面的 行。
  6. 将这些行替换有 保护的 Object[] expectedBodies={ …​…​ expectedBody2</something>"}; to these protected-busybox with those protected String body"; 行:

    protected String body1; protected String body2; protected String body3; protected String body4; protected String body5; protected String body6;
  7. 向下滚动到行 public void testCamelRoute ()会抛出 Exception {,并在它后面直接插入行 body Serial = FileUtils.readFileToString (new File ("src/data/message failing.xml"), "UTF-8"); 如下所示。这些行将指示错误,直到您按照下一节中的指示更新 pom.xml 文件。

    // Valid orders body2 = FileUtils.readFileToString(new File("src/data/message2.xml"), "UTF-8"); body4 = FileUtils.readFileToString(new File("src/data/message4.xml"), "UTF-8"); body5 = FileUtils.readFileToString(new File("src/data/message5.xml"), "UTF-8"); body6 = FileUtils.readFileToString(new File("src/data/message6.xml"), "UTF-8"); // Invalid orders body1 = FileUtils.readFileToString(new File("src/data/message1.xml"), "UTF-8"); body3 = FileUtils.readFileToString(new File("src/data/message3.xml"), "UTF-8");
  8. 向下滚动到在 // TODO Ensure 预期之后直接遵循的行,对我们正在测试的路由有意义
  9. 将以 outputEndpoint.expectedBodiesReceivedInAnyOrder (expectedBodies) 开头的代码块替换为 …​inputEndpoint.sendBody (expectedBody); } 替换为此处显示的行:

    // Invalid orders outputEndpoint.expectedBodiesReceived(body1, body3); // Valid orders for USA output3Endpoint.expectedBodiesReceived(body2, body5, body6); // Valid order for Germany output4Endpoint.expectedBodiesReceived(body4);

    将剩余的代码保留原样。

  10. 保存该文件。
  11. 检查您更新的 BlueprintXmlTest.java 文件是否具有所需的修改。它应该类似如下:

    package tutorial.zooapp.route;
    
    import org.apache.camel.EndpointInject;
    import org.apache.camel.Produce;
    import org.apache.camel.ProducerTemplate;
    import org.apache.camel.builder.RouteBuilder;
    import org.apache.camel.component.mock.MockEndpoint;
    import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
    import org.apache.commons.io.FileUtils;
    import org.junit.Test;
    import java.io.file;
    
    public class BlueprintXmlTest extends CamelBlueprintTestSupport {
    
    	// TODO Create test message bodies that work for the route(s) being tested
    	// Expected message bodies
    	protected String body1;
    	protected String body2;
    	protected String body3;
    	protected String body4;
    	protected String body5;
    	protected String body6;
    	// Templates to send to input endpoints
    	@Produce(uri = "file:src/data?noop=true")
    	protected ProducerTemplate inputEndpoint;
    	@Produce(uri = "direct:OrderFulfillment")
    	protected ProducerTemplate input2Endpoint;
    	// Mock endpoints used to consume messages from the output endpoints and then perform assertions
    	@EndpointInject(uri = "mock:output")
    	protected MockEndpoint outputEndpoint;
    	@EndpointInject(uri = "mock:output2")
    	protected MockEndpoint output2Endpoint;
    	@EndpointInject(uri = "mock:output3")
    	protected MockEndpoint output3Endpoint;
    	@EndpointInject(uri = "mock:output4")
    	protected MockEndpoint output4Endpoint;
    
    	@Test
    	public void testCamelRoute() throws Exception {
    		// Create routes from the output endpoints to our mock endpoints so we can assert expectations
    		context.addRoutes(new RouteBuilder() {
    			@Override
    			public void configure() throws Exception {
    				// Valid orders
    				body2 = FileUtils.readFileToString(new File("src/data/message2.xml"), "UTF-8");
    				body4 = FileUtils.readFileToString(new File("src/data/message4.xml"), "UTF-8");
    				body5 = FileUtils.readFileToString(new File("src/data/message5.xml"), "UTF-8");
    				body6 = FileUtils.readFileToString(new File("src/data/message6.xml"), "UTF-8");
    
    				// Invalid orders
    				body1 = FileUtils.readFileToString(new File("src/data/message1.xml"), "UTF-8");
    				body3 = FileUtils.readFileToString(new File("src/data/message3.xml"), "UTF-8");
    
    				from("file:target/messages/invalidOrders").to(outputEndpoint);
    				from("file:target/messages/validOrders/USA").to(output3Endpoint);
    				from("file:target/messages/validOrders/Germany").to(output4Endpoint);
    				from("direct:OrderFulfillment").to(output2Endpoint);
    			}
    		});
    
    		// Define some expectations
    
    		// TODO Ensure expectations make sense for the route(s) we're testing
    		// Invalid orders
    		outputEndpoint.expectedBodiesReceived(body1, body3);
    
    		// Valid orders for USA
    		output3Endpoint.expectedBodiesReceived(body2, body5, body6);
    
    		// Valid order for Germany
    		output4Endpoint.expectedBodiesReceived(body4);
    
    		// Validate our expectations
    		assertMockEndpointsSatisfied();
    	}
    
    	@Override
    	protected String getBlueprintDescriptor() {
    		return "OSGI-INF/blueprint/blueprint.xml";
    	}
    
    }

修改 pom.xml 文件

您需要将对 commons-io 项目的依赖添加到 ZooOrderApp 项目的 pom.xml 文件中:

  1. Project Explorer 中,选择位于目标文件夹下的 pom.xml,然后在工具的 XML 编辑器中打开它。
  2. 单击页面底部的 pom.xml 选项卡,以打开文件进行编辑。
  3. 将这些行添加到 < dependencies&gt; 部分的末尾:

    <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.5</version>
           <scope>test</scope>
    </dependency>
  4. 保存该文件。

运行 JUnit 测试

运行测试:

  1. 切换到 JBoss 透视图以释放更多工作区。
  2. Project Explorer 中,右键单击 ZooOrderApp 项目。
  3. 选择 Run As JUnit Test

    默认情况下,JUnit 视图在侧边栏中打开。(为了提供更好的视图,将其拖到底部,右面板显示 控制台服务器以及 属性 选项卡。)

    注意

    有时,当 JUnit 首次在项目上运行时,测试会失败。再次运行测试会得到成功的结果。

    如果测试成功运行,您会看到类似如下的内容:

    图 9.2. 成功 JUnit 运行

    JUnit 成功

    当测试失败时,您会看到类似如下的内容:

    图 9.3. JUnit 运行失败

    JUnit 失败
    注意

    如果您的执行环境没有设置为 Java SE 8,则 JUnit 将失败。JUnit 选项卡顶部的消息栏将显示一条错误消息,指出它无法找到正确的 SDK。

    要解决这个问题,打开项目的上下文菜单,然后选择 Run As Run Configuration JRE。点 *Execution environment 字段旁边的 Environments] 按钮 找到并选择 Java SE 8 环境。

  4. 检查输出并采取措施来解决任何测试失败。

    要查看 JUnit 面板中显示的更多错误,请单击面板菜单栏中的 Maximize button 以最大化视图。

    在再次运行 JUnit 测试案例前,从 Project Explorer 中的 ZooOrderApp 项目的 /src/data 文件夹中删除所有 JUnit 生成的测试消息(请参阅 图 9.1 “trace 生成的消息”)。

进一步阅读

要了解有关 JUnit 测试的更多信息,请参阅 JUnit

后续步骤

第 10 章 将项目发布到红帽 Fuse 教程中,您将了解如何将 Apache Camel 项目发布到红帽 Fuse 中。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.