検索

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

download PDF
Red Hat build of Quarkus 1.11

概要

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

はじめに

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

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

注記

このチュートリアルで使用する Quarkus Maven プロジェクトを Quarkus quickstart archive からダウンロードしたり、Quarkus Quickstarts Git リポジトリーをクローンしたりすることもできます。この演習は getting-started-testing ディレクトリーにあります。

前提条件

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

    • Red Hat ビルドの Open JDK は、Red Hat カスタマーポータルの Software Downloads ページからダウンロードできます (ログインが必要です)。
  • Apache Maven 3.8.1 以降がインストールされている。

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

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

Red Hat ドキュメントへのフィードバック (英語のみ)

弊社の技術的な内容についてのフィードバックに感謝します。ご意見をお聞かせください。コメントの追加、Insights の提供、誤字の修正、および質問を行う必要がある場合は、ドキュメントで直接行うこともできます。

注記

Red Hat アカウントがあり、カスタマーポータルにログインしている必要があります。

カスタマーポータルからドキュメントのフィードバックを送信するには、以下の手順を実施します。

  1. Multi-page HTML 形式を選択します。
  2. ドキュメントの右上にある Feedback ボタンをクリックします。
  3. フィードバックを提供するテキストのセクションを強調表示します。
  4. ハイライトされたテキストの横にある Add Feedback ダイアログをクリックします。
  5. ページの右側のテキストボックスにフィードバックを入力し、Submit をクリックします。

フィードバックを送信すると、自動的に問題の追跡が作成されます。Submit をクリックすると表示されるリンクを開き、問題の監視を開始するか、さらにコメントを追加します。

貴重なフィードバックにご協力いただきありがとうございます。

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

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。まずは、マスター (master)、スレーブ (slave)、ブラックリスト (blacklist)、ホワイトリスト (whitelist) の 4 つの用語の置き換えから始めます。この取り組みは膨大な作業を要するため、今後の複数のリリースで段階的に用語の置き換えを実施して参ります。詳細は、Red Hat 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 ファイルで、テスト接続に別のポートを指定できます。別のポートを使用して、セキュアでない HTTP 接続と SSL でセキュア化された接続をテストできます。

手順

  • application.properties ファイルで quarkus.http.test-port プロパティーおよび quarkus.http.test-ssl-port プロパティーを設定します。<port> を、テスト接続に使用するポートの数に置き換えます。

    quarkus.http.test-port=<port>
    quarkus.http.test-ssl-port=<port>

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

    注記

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

第3章 HTTP テスト接続のレスポンスタイムアウトの期間の設定

REST Assured を使用してアプリケーションの REST API をテストする場合、デフォルトの接続およびレスポンスタイムアウトの期間は 30 秒に設定されます。アプリケーションのタイムアウト期間の長さを変更することができます。

手順

  1. アプリケーションプロジェクトで application.properties ファイルを開きます。
  2. quarkus.http.test-timeout プロパティーの値をタイムアウト期間として設定したい期間の長さに設定し、続いてその期間の時間の単位を設定します。

    application.properties

    quarkus.http.test-timeout=<duration>

    たとえば、レスポンスタイムアウトの期間の長さを 10 秒に設定するには、以下を実行します。

    application.properties

    quarkus.http.test-timeout=10s

第4章 テストへの 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 コンポーネントです。

第5章 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 はテストに注入されます。

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

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

手順

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

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

    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 サービスを直接評価する簡単なテストです。

第7章 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
    MockExternalService は、ExternalService が使用されている場所に注入されます。この例では、MockExternalServiceUsesExternalService で使用されます。
    注記

    @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());
        }
    }

第8章 関連情報

改訂日時: 2023-05-16

法律上の通知

Copyright © 2023 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.