第9章 JUnit を使用したルートのテスト

このチュートリアルでは、New Camel Test Case ウィザードを使用してルートのテストケースを作成し、ルートをテストする方法を示します。

概要

New Camel Test Case ウィザードは、定型的な JUnit テストケースを生成します。ルートを作成または変更する場合 (たとえば、プロセッサーを追加する場合)、作成または変更したルートに固有の期待値とアサーションを追加するために、生成されたテストケースを作成または変更する必要があります。これにより、テストがルートに対して有効であることが保証されます。

ゴール

このチュートリアルでは、次のタスクを完了します。

  • JUnit テストケースを保存する /src/test/ フォルダーを作成する
  • ZooOrderApp プロジェクトの JUnit テストケースを生成する
  • 新しく生成された JUnit テストケースを変更します
  • ZooOrderApp プロジェクトの pom.xml ファイルを変更する
  • 新しい JUnit テストケースで ZooOrderApp を実行する
  • 出力を観察します

前提条件

  1. このチュートリアルを開始するには、次のいずれかの結果である ZooOrderApp プロジェクトが必要です。

  2. Project Explorer で、ZooOrderApp プロジェクトの /src/data/ ディレクトリーおよび /target/messages/ サブディレクトリーからトレースにより生成されたメッセージを削除します。トレースにより生成されたメッセージは、ID- 接頭辞で始まります。例えば、図9.1「トレースで生成されたメッセージ」トレースによって生成された 8 つのメッセージを示します。

    図9.1 トレースで生成されたメッセージ

    tutTraceGenMsgs

    トレースで生成されたすべてのメッセージをバッチで選択し、右クリックして Delete を選択します。

src/test フォルダーの作成

ZooOrderApp プロジェクトの JUnit テストケースを作成する前に、ビルドパスに含まれるフォルダーを作成する必要があります。

  1. Project ExplorerZooOrderApp プロジェクトを右クリックし、NewFolder を選択します。
  2. New Folder ダイアログで、プロジェクトツリーペインで ZooOrderApp ノードを展開し、src フォルダーを選択します。

    ZooOrderApp/srcEnter or select the parent folder フィールドに表示されるのを確認してください。

  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. ビルドパスを選択して、メニューオプションを表示します。

      Remove from Build Path のメニューオプションで、/src/test/java フォルダーが現在ビルドパスに含まれていることが確認できます。

      tutJavaFolderOnBldPath

JUnit テストケースの作成

ZooOrderApp プロジェクトの JUnit テストケースを作成するには、以下を実行します。

  1. Project Explorersrc/test/java を選択します。
  2. 右クリックして、NewCamel Test Case を選択します。

    NewCamTstCaseTut
  3. Camel JUnit Test Case ウィザードで、Source folder フィールドに ZooOrderApp/src/test/java が含まれるようにします。適切なフォルダーを見つけるには、 browse button をクリックします。
  4. Package フィールドに tutorial.zooapp.route と入力します。このパッケージには、新しいテストケースが含まれます。
  5. Camel XML file under test フィールドで、 browse button をクリックし、XML ファイルをフィルターするように設定されたファイルエクスプローラーを開き、ZooOrderApp プロジェクトの blueprint.xml ファイルを選択します。

    tutCamXMLUnderTst
  6. OK をクリックします。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";
	}

}

この生成された JUnit テストケースは ZooOrderApp プロジェクトには不十分なため、正常に実行できません。「BlueprintXmlTest ファイルの変更」および「pom.xml ファイルの変更」に記載されているように、テストケースおよびプロジェクトの pom.xml を変更する必要があります。

BlueprintXmlTest ファイルの変更

BlueprintXmlTest.java ファイルを変更し、以下を実行する必要があります。

  • 必要なファイル機能をサポートするいくつかのクラスをインポートします
  • さまざまなソース .xml ファイルの内容を保持する変数を作成する
  • ソース .xml ファイルの内容を読み取る
  • 適切な期待値を定義します

次の手順に従って、BlueprintXmlTest.java ファイルを変更します。

  1. Project Explorer で、ZooOrderApp プロジェクトを展開して BlueprintXmlTest.java ファイルを公開します。

    tutBlueprintXMLTestProjExp
  2. BlueprintXmlTest.java ファイルを開きます。
  3. Java エディターで import org.apache.camel.EndpointInject; の横にある展開ボタンをクリックしてリストを展開します。
  4. 太字で示されている 2 行を追加します。最初の行を追加するとエラーが発生しますが、次のセクションで指示どおりに 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. // Expected message bodies のすぐ後の行までスクロールします。
  6. protected Object[] expectedBodies={ …​…​ expectedBody2</something>"}; の行を 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() throws Exception { の行まで下方向にスクロールし、その直後に以下のように body# = FileUtils.readFileToString(new File("src/data/message#.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 expectations make sense for the route(s) we're testing の直後の行まで下方向にスクロールします。
  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 で、target フォルダーの下の pom.xml を選択し、ツールの XML エディターで開きます。
  2. ページの下部にある pom.xml タブをクリックして、ファイルを表示して編集します。
  3. <dependencies> セクションの最後に以下の行を追加します。

    <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.5</version>
           <scope>test</scope>
    </dependency>
  4. ファイルを保存します。

JUnit テストの実行

テストを実行するには:

  1. より多くのワークスペースを解放するには、JBoss パースペクティブに切り替えます。
  2. Project ExplorerZooOrderApp プロジェクトを右クリックします。
  3. Run AsJUnit Test を選択します。

    デフォルトでは、JUnit ビューはサイドバーで開きます。(見やすくするには、ConsoleServers、および Properties のタブが表示されている右下のパネルにドラッグします。)

    注記

    プロジェクトで JUnit を初めて実行すると、テストが失敗することがあります。通常、テストを再実行すると、成功します。

    テストが正常に実行されると、次のように表示されます。

    図9.2 JUnit の実行が成功しました

    JUnit の成功

    テストが失敗すると、次のように表示されます。

    図9.3 JUnit の実行に失敗しました

    JUnit の失敗
    注記

    実行環境が Java SE 8 に設定されていない場合、JUnit は失敗します。JUnit タブの上部にあるメッセージバーに、正しい SDK が見つからないことを示すエラーメッセージが表示されます。

    この問題を解決するには、プロジェクトのコンテキストメニューを開き、Run AsRun ConfigurationsJRE を選択します。Environments] button next to the *Execution environment フィールドをクリックして、Java SE 8 環境を見つけて選択します。

  4. 出力を調べて、テストの失敗を解決するためのアクションを実行します。

    JUnit パネルに表示されるエラーの詳細を表示するには、パネルのメニューバーの Maximize button をクリックし、ビューを最大化します。

    JUnit テストケースを再度実行する前に、Project Explorer で ZooOrderApp プロジェクトの /src/data フォルダーから JUnit が生成するテストメッセージを削除します (図9.1「トレースで生成されたメッセージ」を参照)。

関連資料

JUnit テストの詳細は、JUnit を参照してください。

次のステップ

10章プロジェクトを Red Hat Fuse に公開するチュートリアルでは、Apache Camel プロジェクトを Red Hat Fuse に公開する方法を学びます。