Quarkus アプリケーションのテスト


Red Hat build of Quarkus 1.7

概要

本ガイドでは、Quarkus Getting Started アプリケーションをテストする方法について説明します。

前書き

アプリケーション開発者は、Red Hat ビルドの Quarkus を使用して、OpenShift 環境およびサーバーレス環境で実行される Java で書かれたマイクロサービスベースのアプリケーションを作成できます。ネイティブ実行可能ファイルにコンパイルされたアプリケーションは、メモリーのフットプリントが小さく、起動時間は高速です。

本ガイドでは、Apache Maven を使用して JVM モードで Quarkus Getting Started プロジェクトをテストする方法と、リソースをテストに注入する方法を説明します。『Quarkus スタートガイド』 で作成したテストを展開します。

前提条件

  • OpenJDK (JDK) 11 がインストールされ、JAVA_HOME 環境変数が Java SDK の場所を指定していること。

    • Red Hat ビルドの Open JDK は、Red Hat カスタマーポータルの Software Downloads ページから入手可能です (ログインが必要です)。
  • Apache Maven 3.6.3 以降がインストールされていること。

  • Quarkus Getting Started プロジェクトを完了していること。

    • Quarkus Getting Started プロジェクトのビルド方法は、『Quarkus スタートガイド』 を参照してください。
    • あるいは、Quarkus quickstart archive をダウンロードするか、Quarkus Quickstarts Git リポジトリーをクローンしてください。この例は getting-started ディレクトリーにあります。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。まずは、マスター (master)、スレーブ (slave)、ブラックリスト (blacklist)、ホワイトリスト (whitelist) の 4 つの用語の置き換えから始めます。この取り組みは膨大な作業を要するため、今後の複数のリリースで段階的に用語の置き換えを実施して参ります。詳細は、弊社 の CTO、Chris Wright のメッセージ を参照してください。

第1章 テスト依存関係の確認

このチュートリアルでは、Quarkus Getting Started プロジェクトが完了済みで、プロジェクト pom.xml ファイルに quarkus-junit5 および rest-assured 依存関係が含まれている必要があります。Quarkus Getting Started の演習を完了した場合、または完了済みのサンプルをダウンロードした場合に、これらの依存関係が表示されます。

  • quarkus-junit5 依存関係は、テストフレームワークを制御する @QuarkusTest アノテーションを提供するため、テストに必要です。
  • rest-assured 依存関係は必要ありませんが、HTTP エンドポイントをテストするための便利な方法として使用できます。

    注記

    Quarkus は正しい URL を自動的に設定するインテグレーションを提供するため、設定は必要ありません。

手順

  1. Getting Started プロジェクトの pom.xml ファイルを開きます。
  2. 以下の依存関係がファイルに含まれていることを確認し、必要な場合は追加します。

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-junit5</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <scope>test</scope>
    </dependency>
  3. pom.xml ファイルに maven-surefire-plugin が含まれることを確認します。このチュートリアルでは JUnit 5 フレームワークを使用することから、maven-surefire-plugin のバージョンを設定する必要があります (デフォルトのバージョンでは JUnit 5 に対応していないため)。

    <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
           <systemProperties>
              <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
           </systemProperties>
        </configuration>
    </plugin>
  4. java.util.logging.manager システムプロパティーを設定し、テスト用に適切なログマネージャーを使用します。
  5. GreetingResourceTest.java ファイルに以下の内容が含まれていることを確認し、必要な場合は追加します。

    package org.acme.quickstart;
    
    import io.quarkus.test.junit.QuarkusTest;
    import org.junit.jupiter.api.Test;
    
    import java.util.UUID;
    
    import static io.restassured.RestAssured.given;
    import static org.hamcrest.CoreMatchers.is;
    
    @QuarkusTest
    public class GreetingResourceTest {
    
        @Test
        public void testHelloEndpoint() {
            given()
              .when().get("/hello")
              .then()
                 .statusCode(200)
                 .body(is("hello"));
        }
    
        @Test
        public void testGreetingEndpoint() {
            String uuid = UUID.randomUUID().toString();
            given()
              .pathParam("name", uuid)
              .when().get("/hello/greeting/{name}")
              .then()
                .statusCode(200)
                .body(is("hello " + uuid));
        }
    
    }
  6. テストを実行するには、以下のコマンドを入力します。

    ./mvnw clean verify

    IDE から直接テストを実行することもできます。

注記

このテストでは、HTTP を使用して REST エンドポイントを直接テストします。テストがトリガーされると、テストの実行前にアプリケーションが起動します。

第2章 テストポートの指定

デフォルトでは、Quarkus テストはポート 8081 で実行され、実行中のアプリケーションとの競合が発生しないようにします。これにより、アプリケーションを並行して実行中にテストを実行できます。

手順

  • プロジェクトのテスト中に使用するポートを指定するには、プロジェクト application.properties ファイルに quarkus.http.test-port プロパティーを設定します。<port> は、テストするポートに置き換えます。

    quarkus.http.test-port=<port>

    ポート番号を 0 に設定すると、オペレーティングシステムは、システムで利用可能なポートの範囲からランダムなポートを割り当てることができます。

    注記

    Quarkus は、テストの実行前に RestAssured が使用するデフォルトポートを更新する RestAssured インテグレーションを提供するため、追加の設定は必要ありません。

第3章 テストへの URL の注入

別のクライアントを使用する場合は、Quarkus @TestHTTPResource アノテーションを使用して、テスト予定のアプリケーションの URL を test クラスのフィールドに直接注入します。このフィールドには、タイプ StringURL、または URI を使用できます。このアノテーションにテストパスを指定することもできます。この演習では、静的リソースをロードする簡単なテストを作成します。

手順

  1. 以下の内容を含む src/main/resources/META-INF/resources/index.html ファイルを作成します。

    <html>
        <head>
            <title>Testing Guide</title>
        </head>
        <body>
            Information about testing
        </body>
    </html>
  2. 以下の内容で StaticContentTest.java ファイルを作成し、index.html に適切なサービスが提供されていることをテストします。

    package org.acme.quickstart;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    import java.nio.charset.StandardCharsets;
    
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import io.quarkus.test.common.http.TestHTTPResource;
    import io.quarkus.test.junit.QuarkusTest;
    
    @QuarkusTest
    public class StaticContentTest {
    
        @TestHTTPResource("index.html") 1
        URL url;
    
        @Test
        public void testIndexHtml() throws Exception {
            try (InputStream in = url.openStream()) {
                String contents = readStream(in);
                Assertions.assertTrue(contents.contains("<title>Testing Guide</title>"));
            }
        }
    
        private static String readStream(InputStream in) throws IOException {
            byte[] data = new byte[1024];
            int r;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            while ((r = in.read(data)) > 0) {
                out.write(data, 0, r);
            }
            return new String(out.toByteArray(), StandardCharsets.UTF_8);
        }
    }
    1
    @TestHTTPResource アノテーションを使用すると、Quarkus インスタンスの URL を直接注入できます。アノテーションの値は URL の path コンポーネントです。

第4章 CDI Bean のテストへの注入

ユニットテストを実行し、CDI Bean を直接テストできます。Quarkus により、@Inject アノテーションを使用して CDI Bean をテストに注入できます。実際、Quarkus のテストでは完全な CDI Bean であるため、完全な CDI 機能を使用できます。

注記

ネイティブテストで注入を使用することはできません。

手順

  • 以下の内容を含む GreetingServiceTest.java ファイルを作成します。

    package org.acme.quickstart;
    
    import javax.inject.Inject;
    
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    import io.quarkus.test.junit.QuarkusTest;
    
    @QuarkusTest
    public class GreetingServiceTest {
    
        @Inject 1
        GreetingService service;
    
        @Test
        public void testGreetingService() {
            Assertions.assertEquals("hello Quarkus", service.greeting("Quarkus"));
        }
    }
    1
    GreetingService Bean はテストに注入されます。

第5章 テストへのインターセプターの適用

Quarkus テストは完全な CDI Bean であるため、通常通りに CDI インターセプターを適用できます。たとえば、トランザクションのコンテキスト内であるテスト方法を実行する場合は、@Transactional アノテーションをその方法に適用できます。また、独自のテストステレオタイプを作成することもできます。

手順

  1. quarkus-narayana-jta 依存関係を pom.xml ファイルに追加します。

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-narayana-jta</artifactId>
    </dependency>
  2. 以下の import ステートメントが TransactionalQuarkusTest.java に含まれることを確認してください。

    package org.acme.quickstart;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import javax.enterprise.inject.Stereotype;
    import javax.transaction.Transactional;
    
    import io.quarkus.test.junit.QuarkusTest;
  3. @TransactionalQuarkusTest アノテーションを作成します。

    @QuarkusTest
    @Stereotype
    @Transactional
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface TransactionalQuarkusTest {
    }
  4. このアノテーションを、@QuarkusTest アノテーションおよび @Transactional アノテーションの両方を適用したかのように動作するテストクラスに適用します。

    @TransactionalQuarkusTest
    public class TestStereotypeTestCase {
    
        @Inject
        UserTransaction userTransaction;
    
        @Test
        public void testUserTransaction() throws Exception {
            Assertions.assertEquals(Status.STATUS_ACTIVE, userTransaction.getStatus());
        }
    
    }

    これは、HTTP を使用せずに greeting サービスを直接評価する簡単なテストです。

第6章 CDI Bean のモック化

Quarkus により、特定のテスト用に一部の CDI Bean をモック化できます。

以下の方法の 1 つを使用して、オブジェクトをモック化できます。

  • src/test/java ディレクトリーのクラスでモック化する Bean を上書きし、@Alternative および @Priority(1) のアノテーションを Bean に配置します。
  • io.quarkus.test.Mock ステレオタイプアノテーションを使用します。@Mock アノテーションには @Alternative@Priority(1)、および @Dependent のアノテーションが含まれます。

以下の手順では、@Alternative アノテーションを使用して外部サービスをモック化する方法を説明します。

手順

  1. 以下の例に示すような src/main/java ディレクトリーに ExternalService を作成します。

    package org.acme.quickstart;
    
    import javax.enterprise.context.ApplicationScoped;
    
    @ApplicationScoped
    public class ExternalService {
    
        public String service() {
            return "external";
        }
    
    }
  2. src/main/java ディレクトリーで ExternalService を使用する UsesExternalService クラスを作成します。

    package org.acme.quickstart;
    
    import javax.enterprise.context.ApplicationScoped;
    import javax.inject.Inject;
    
    @ApplicationScoped
    public class UsesExternalService {
    
        @Inject
        ExternalService externalService;
    
        public String doSomething() {
            return externalService.service();
        }
    }
  3. 以下の例に示すような src/test/java ディレクトリーにテストを作成します。

    package org.acme.quickstart;
    
    import javax.inject.Inject;
    
    import io.quarkus.test.junit.QuarkusTest;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    @QuarkusTest
    class UsesExternalServiceTest {
    
        @Inject
        UsesExternalService usesExternalService;
    
        @Test
        public void testDoSomething() {
            Assertions.assertEquals("external", usesExternalService.doSomething());
        }
    }
  4. @Alternative アノテーションを使用する src/test/javaMockExternalService を作成します。

    package org.acme.quickstart;
    
    import javax.annotation.Priority;
    import javax.enterprise.context.ApplicationScoped;
    import javax.enterprise.inject.Alternative;
    
    @Alternative
    @Priority(1)
    @ApplicationScoped
    public class MockExternalService extends ExternalService { 1
    
        @Override
        public String service() {
            return "mock";
        }
    }
    1
    ExternalService が使用されている場所に、MockExternalService が注入されます。この例では、MockExternalService は、UsesExternalService で使用されます。
    注記

    @Alternative@Priority(1) および @Dependent のアノテーションの代わりに @Mock アノテーションを使用できます。

    以下の例は、@Mock アノテーションを使用する MockExternalService クラスを作成する方法を示しています。

    import javax.enterprise.context.ApplicationScoped;
    
    import io.quarkus.test.Mock;
    
    @Mock
    @ApplicationScoped
    public class MockExternalService extends ExternalService {
    
        @Override
        public String service() {
            return "mock";
        }
    }
  5. テストで、アサートされた文字列を "external" から "mock" に変更します。

    package org.acme.quickstart;
    
    import javax.inject.Inject;
    
    import io.quarkus.test.junit.QuarkusTest;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    
    @QuarkusTest
    class UsesExternalServiceTest {
    
        @Inject
        UsesExternalService usesExternalService;
    
        @Test
        public void testDoSomething() {
            Assertions.assertEquals("mock", usesExternalService.doSomething());
        }
    }

第7章 その他のリソース

改訂日時: 2021-04-27 03:44:21 UTC

法律上の通知

Copyright © 2021 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.