The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

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

Quarkusアプリケーションのテスト方法について説明します。このガイドでは、以下の内容について説明します。

  • JVM モードでのテスト

  • ネイティブモードでのテスト

  • テストへのリソースの注入

1. 前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 11+ がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.8.1+

  • 使用したい場合、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • 入門ガイドに掲載されている、完了済のGreeterアプリケーション

2. アーキテクチャ

このガイドでは、入門ガイドの一部として作成された最初のテストを拡張します。テストへのインジェクションと、ネイティブ実行可能ファイルをテストする方法もカバーしています。

Quarkus は継続テストをサポートしていますが、これについては 継続テストガイド で説明しています。

3. ソリューション

次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。

Git リポジトリーのクローンを作成: git clonehttps://github.com/quarkusio/quarkus-quickstarts.git、または アーカイブ をダウンロードします。

ソリューションは getting-started-testing ディレクトリー にあります。

このガイドでは、 getting-started ディレクトリーの完成したアプリケーションをすでに持っていることを前提としています。

4. JVM モードを使用した HTTP ベースのテストの要約

「はじめに」のサンプルから始めた場合は、正しいツールマップの設定を含めて、すでにテストが完了しているはずです。

ビルドファイルには、2 つのテスト依存関係が表示されます。

Maven
<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>
Gradle
dependencies {
    testImplementation("io.quarkus:quarkus-junit5")
    testImplementation("io.rest-assured:rest-assured")
}

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

JUnit 5を使用しているので、 Surefire Maven Pluginのバージョンを設定する必要があります。デフォルトのバージョンはJUnit 5をサポートしていない為です。

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <configuration>
       <systemPropertyVariables>
          <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          <maven.home>${maven.home}</maven.home>
       </systemPropertyVariables>
    </configuration>
</plugin>

また、 java.util.logging.manager システムプロパティーを設定して、テストが正しい logmanager と maven.home を使用して、${maven.home}/conf/settings.xml からのカスタム設定が適用されるようにしています (存在する場合)。

プロジェクトには簡単なテストも含まれているはずです:

package org.acme.getting.started.testing;

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

}

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

4.1. テストポートの制御

Quarkusはデフォルトではポート 8080 をリッスンしますが、テストを実行する場合はデフォルトで 8081 をリッスンします。これにより、アプリケーションを並行して実行しながらテストを実行することができます。

テストポートの変更

application.propertiesquarkus.http.test-port を設定することで、を HTTP 用にテストで使われるポートを設定出来、 quarkus.http.test-ssl-port を設定することで HTTPS 用にテストで使用するポートを設定することが出来ます。

quarkus.http.test-port=8083
quarkus.http.test-ssl-port=8446

0 を使用すると、(オペレーティングシステムによって割り当てられた)ランダムなポートが使用されることになります。

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

4.2. HTTP インタラクションタイムアウトの制御

テストで REST Assured を使用する場合、接続と応答のタイムアウトは 30 秒に設定されます。この設定は quarkus.http.test-timeout プロパティーでオーバーライドできます:

quarkus.http.test-timeout=10s

4.3. URI の挿入

URLをテストに直接注入することも可能で、別のクライアントを使用するのが簡単になります。これは @TestHTTPResource アノテーションで行います。

静的なリソースをロードするための簡単なテストを書いてみましょう。まず、シンプルなHTMLファイルを src/main/resources/META-INF/resources/index.html に作成します:

<html>
    <head>
        <title>Testing Guide</title>
    </head>
    <body>
        Information about testing
    </body>
</html>

これが正しく提供されているかどうかを確認するための簡単なテストを作成します:

package org.acme.getting.started.testing;

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 IOException {
        try (InputStream in = url.openStream()) {
            String contents = new String(in.readAllBytes(), StandardCharsets.UTF_8);
            Assertions.assertTrue(contents.contains("<title>Testing Guide</title>"));
        }
    }
}
1 このアノテーションを使用すると、QuarkusインスタンスのURLを直接注入することができます。アノテーションの値は、URLのパス部分になります。

今のところ @TestHTTPResource では、URL の URI , URL , String 表現を注入することができます。

5. 特定のエンドポイントのテスト

RESTassured と @TestHTTPResource の両方で、パスをハードコーディングするのではなく、テストするエンドポイントクラスを指定することができます。これは現在、JAX-RS エンドポイント、サーブレット、リアクティブルートの両方をサポートしています。これにより、特定のテストがどのエンドポイントをテストしているかを正確に確認することが非常に簡単になりました。

これらの例では、以下のようなエンドポイントを想定しています:

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}
これは現在、JAX-RS のコンテキストパスを設定するための @ApplicationPath() アノテーションをサポートしていません。カスタムのコンテキストパスを設定したい場合は、代わりに quarkus.resteasy.path の設定値を使用してください。

5.1. テストHTTPリソース

io.quarkus.test.common.http.TestHTTPEndpoint アノテーションを使用してエンドポイントのパスを指定することが出来、指定されたエンドポイントからパスが抽出されます。 TestHTTPResource エンドポイントにも値を指定すると、エンドポイントパスの最後に追加されます。

package org.acme.getting.started.testing;

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.TestHTTPEndpoint;
import io.quarkus.test.common.http.TestHTTPResource;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class StaticContentTest {

    @TestHTTPEndpoint(GreetingResource.class)  (1)
    @TestHTTPResource
    URL url;

    @Test
    public void testIndexHtml() throws IOException {
        try (InputStream in = url.openStream()) {
            String contents = new String(in.readAllBytes(), StandardCharsets.UTF_8);
            Assertions.assertEquals("hello", contents);
        }
    }
}
1 GreetingResource@Path("/hello") とアノテーションされているので、注入された URL は /hello で終わります。

5.2. RESTassured

RESTassured ベースパス (すなわち、すべてのリクエストのルートとなるデフォルトパス) を制御するには、 io.quarkus.test.common.http.TestHTTPEndpoint アノテーションを使用できます。これはクラスやメソッドレベルで適用できます。グリーティングリソースをテストするには、以下のようにします:

package org.acme.getting.started.testing;

import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import org.junit.jupiter.api.Test;

import java.util.UUID;

import static io.restassured.RestAssured.when;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
@TestHTTPEndpoint(GreetingResource.class) (1)
public class GreetingResourceTest {

    @Test
    public void testHelloEndpoint() {
        when().get()    (2)
          .then()
             .statusCode(200)
             .body(is("hello"));
    }
}
1 これにより、RESTAssured はすべてのリクエストの前に /hello を付けます。
2 このテストでは /hello がデフォルトなので、ここでパスを指定する必要はないことに注意してください。

6. テストへの注入

これまでは、HTTP エンドポイントを介してアプリをテストする統合スタイルのテストしか取り上げてきませんでしたが、ユニットテストを行い、Beanを直接テストしたい場合はどうでしょうか?

Quarkusでは、 @Inject アノテーションを介してテストにCDI Beanを注入できるようにすることで、これをサポートしています(実際、Quarkusのテストは完全なCDI Beanなので、すべてのCDI機能を使用することができます)。HTTPを使用せずにグリーティングサービスを直接テストするシンプルなテストを作成してみましょう。

package org.acme.getting.started.testing;

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がテストに注入されます。

7. テストへのインターセプターの適用

前述したように、Quarkusのテストは実際には完全なCDI Beanであり、通常のようにCDIインターセプターを適用することができます。例えば、トランザクションのコンテキスト内でテストメソッドを実行したい場合、 @Transactional アノテーションをメソッドに適用するだけで、トランザクションインターセプターがそれを処理します。

In addition to this you can also create your own test stereotypes. For example, we could create a @TransactionalQuarkusTest as follows:

@QuarkusTest
@Stereotype
@Transactional
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TransactionalQuarkusTest {
}

このアノテーションをテストクラスに適用すると、 @QuarkusTest@Transactional の両方のアノテーションを適用したかのように動作します。

@TransactionalQuarkusTest
public class TestStereotypeTestCase {

    @Inject
    UserTransaction userTransaction;

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

}

8. テストとトランザクション

テストでは標準のQuarkus @Transactional アノテーションを使用することができますが、これは、テストでデータベースに加えた変更が永続化されることを意味します。テストの終了時に変更をロールバックしたい場合は、 io.quarkus.test.TestTransaction アノテーションを使用することができます。これは、トランザクション内でテストメソッドを実行しますが、テストメソッドが完了したらロールバックして、データベースの変更を元に戻します。

9. QuarkusTest* コールバックによる強化

インターセプターの代わりに、あるいはインターセプターに加えて、以下のコールバックインターフェースを実装することで、 すべての @QuarkusTest クラスを充実させることができます。

  • io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback

  • io.quarkus.test.junit.callback.QuarkusTestAfterConstructCallback

  • io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback

  • io.quarkus.test.junit.callback.QuarkusTestBeforeTestExecutionCallback

  • io.quarkus.test.junit.callback.QuarkusTestAfterTestExecutionCallback

  • io.quarkus.test.junit.callback.QuarkusTestAfterEachCallback

このようなコールバックの実装は、 java.util.ServiceLoader で定義されている「サービスプロバイダ」として登録する必要があります。

例えば、以下のようなサンプルコールバックです:

package org.acme.getting.started.testing;

import io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback;
import io.quarkus.test.junit.callback.QuarkusTestMethodContext;

public class MyQuarkusTestBeforeEachCallback implements QuarkusTestBeforeEachCallback {

    @Override
    public void beforeEach(QuarkusTestMethodContext context) {
        System.out.println("Executing " + context.getTestMethod());
    }
}

次のように、src/main/resources/META-INF/services/io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback を介して登録する必要があります。

org.acme.getting.started.testing.MyQuarkusTestBeforeEachCallback
テストクラスやメソッドからアノテーションを読み込んで、コールバックが何をするかを制御することができます。
BeforeEachCallback のような JUnit Jupiter コールバックインターフェイスを使うことも可能ですが、QuarkusはJUnitが把握しないカスタムクラスローダーでテストを実行する必要がある為、クラスローディングの問題にぶつかるかもしれません。

10. 異なるプロファイルのテスト

So far in all our examples we only start Quarkus once for all tests. Before the first test is run Quarkus will boot, then all tests will run, then Quarkus will shut down at the end. This makes for a very fast testing experience however it is a bit limited as you can’t test different configurations.

この問題を回避するために、Quarkusはテストプロファイルの考え方をサポートしています。以前に実行したテストとは異なるプロファイルを持つテストがある場合、Quarkusはテストを実行する前にシャットダウンされ、新しいプロファイルで開始されます。これは、テスト時間にシャットダウン/起動サイクルが追加されるため、明らかに少し遅くなりますが、非常に大きな柔軟性が得られます。

To reduce the amount of times Quarkus needs to restart, io.quarkus.test.junit.util.QuarkusTestProfileAwareClassOrderer is registered as a global ClassOrderer as described in the JUnit 5 User Guide. The behavior of this ClassOrderer is configurable via junit-platform.properties (see the source code or javadoc for more details). It can also be disabled entirely by setting another ClassOrderer that is provided by JUnit 5 or even your own custom one. + Please note that as of JUnit 5.8.2 only a single junit-platform.properties is picked up and a warning is logged if more than one is found. If you encounter such warnings, you can get rid of them by removing the Quarkus-supplied junit-platform.properties from the classpath via an exclusion:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-junit5</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5-properties</artifactId>
        </exclusion>
    </exclusions>
</dependency>

10.1. プロフィールの書き方

テストプロファイルを実装するには、 io.quarkus.test.junit.QuarkusTestProfile .

package org.acme.getting.started.testing;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.quarkus.test.junit.QuarkusTestProfile;
import io.quarkus.test.junit.QuarkusTestProfile.TestResourceEntry;

public class MockGreetingProfile implements QuarkusTestProfile { (1)

    /**
     * Returns additional config to be applied to the test. This
     * will override any existing config (including in application.properties),
     * however existing config will be merged with this (i.e. application.properties
     * config will still take effect, unless a specific config key has been overridden).
     *
     * Here we are changing the JAX-RS root path.
     */
    @Override
    public Map<String, String> getConfigOverrides() {
        return Collections.singletonMap("quarkus.resteasy.path","/api");
    }

    /**
     * Returns enabled alternatives.
     *
     * This has the same effect as setting the 'quarkus.arc.selected-alternatives' config key,
     * however it may be more convenient.
     */
    @Override
    public Set<Class<?>> getEnabledAlternatives() {
        return Collections.singleton(MockGreetingService.class);
    }

    /**
     * Allows the default config profile to be overridden. This basically just sets the quarkus.test.profile system
     * property before the test is run.
     *
     * Here we are setting the profile to test-mocked
     */
    @Override
    public String getConfigProfile() {
        return "test-mocked";
    }

    /**
     * Additional {@link QuarkusTestResourceLifecycleManager} classes (along with their init params) to be used from this
     * specific test profile.
     *
     * If this method is not overridden, then only the {@link QuarkusTestResourceLifecycleManager} classes enabled via the {@link io.quarkus.test.common.QuarkusTestResource} class
     * annotation will be used for the tests using this profile (which is the same behavior as tests that don't use a profile at all).
     */
    @Override
    public List<TestResourceEntry> testResources() {
        return Collections.singletonList(new TestResourceEntry(CustomWireMockServerManager.class));
    }


    /**
     * If this returns true then only the test resources returned from {@link #testResources()} will be started,
     * global annotated test resources will be ignored.
     */
    @Override
    public boolean disableGlobalTestResources() {
        return false;
    }

    /**
     * The tags this profile is associated with.
     * When the {@code quarkus.test.profile.tags} System property is set (its value is a comma separated list of strings)
     * then Quarkus will only execute tests that are annotated with a {@code @TestProfile} that has at least one of the
     * supplied (via the aforementioned system property) tags.
     */
    @Override
    public Set<String> tags() {
        return Collections.emptySet();
    }

    /**
     * The command line parameters that are passed to the main method on startup.
     */
    @Override
    public String[] commandLineParameters() {
        return new String[0];
    }

    /**
     * If the main method should be run.
     */
    @Override
    public boolean runMainMethod() {
        return false;
    }

    /**
     * If this method returns true then all {@code StartupEvent} and {@code ShutdownEvent} observers declared on application
     * beans should be disabled.
     */
    @Override
    public boolean disableApplicationLifecycleObservers() {
        return false;
    }
}
1 これらのメソッドにはすべてデフォルトの実装があるため、オーバーライドが必要なメソッドのみオーバーライドします。

これでプロファイルを定義したので、それをテストクラスに含める必要があります。そのためには、テストクラスに @TestProfile(MockGreetingProfile.class) アノテーションを付けます。

テストプロファイルの設定はすべて単一のクラスに保存されているので、前回のテストが同じ設定で実行されたかどうかが簡単にわかります。

10.2. 特定のテストの実行

Quarkus は、テストの実行を特定の @TestProfile アノテーションを持つテストに制限できます。これは、QuarkusTestProfiletags メソッドを quarkus.test.profile.tags システムプロパティーと組み合わせて利用することで機能します。

基本的に、quarkus.test.profile.tags の値と一致するタグが少なくとも 1 つある QuarkusTestProfile はアクティブであると見なされ、アクティブなプロファイルの @TestProfile でアノテーションが付けられたすべてのテストが実行されますが、それ以外はスキップされます。以下は、その典型的な例です。

まず、次のようないくつかの QuarkusTestProfile 実装を定義しましょう。

public class Profiles {

    public static class NoTags implements QuarkusTestProfile {

    }

    public static class SingleTag implements QuarkusTestProfile {
        @Override
        public Set<String> tags() {
            return Collections.singleton("test1");
        }
    }

    public static class MultipleTags implements QuarkusTestProfile {
        @Override
        public Set<String> tags() {
            return new HashSet<>(Arrays.asList("test1", "test2"));
        }
    }
}

ここで、次のテストがあると仮定します。

@QuarkusTest
public class NoQuarkusProfileTest {

    @Test
    public void test() {
        // test something
    }
}
@QuarkusTest
@TestProfile(Profiles.NoTags.class)
public class NoTagsTest {

    @Test
    public void test() {
        // test something
    }
}
@QuarkusTest
@TestProfile(Profiles.SingleTag.class)
public class SingleTagTest {

    @Test
    public void test() {
        // test something
    }
}
@QuarkusTest
@TestProfile(Profiles.MultipleTags.class)
public class MultipleTagsTest {

    @Test
    public void test() {
        // test something
    }
}

次のシナリオを考えてみましょう。

  • quarkus.test.profile.tags が設定されていない: すべてのテストが実行されます。

  • quarkus.test.profile.tags=foo: この場合、QuarkusTestProfile 実装で定義されたタグはいずれも quarkus.test.profile.tags の値と一致しないため、テストは実行されません。@TestProfile でアノテーションが付けられていないため、NoQuarkusProfileTest も実行されないことに注意してください。

  • quarkus.test.profile.tags=test1: この場合、それぞれの QuarkusTestProfile 実装のタグが quarkus.test.profile.tags の値と一致するため、SingleTagTestMultipleTagsTest が実行されます。

  • quarkus.test.profile.tags=test1,test3: この場合、前の場合と同じテストが実行されます。

  • quarkus.test.profile.tags=test2,test3: この場合、MultipleTagsTest は、tags メソッドが quarkus.test.profile.tags の値と一致する唯一の QuarkusTestProfile 実装であるため、MultipleTagsTest のみ実行されます。

11. モックサポート

Quarkusでは、2つの異なるアプローチを使用したモックオブジェクトの使用をサポートしています。CDIの代替品を使用してすべてのテストクラスのBeanをモックアウトするか、 QuarkusMock を使用してテストごとにBeanをモックアウトすることができます。

11.1. CDI @Alternative メカニズム

これを使用するには、 src/test/java ディレクトリーのクラスでモックしたいBeanをオーバーライドし、 @Alternative@Priority(1) アノテーションをBeanに配置するだけです。あるいは、便利な io.quarkus.test.Mock ステレオタイプアノテーションを使用することもできます。この組み込みステレオタイプは、 @Alternative@Priority(1)@Dependent を宣言します。例えば、以下のようなサービスがあるとします:

@ApplicationScoped
public class ExternalService {

    public String service() {
        return "external";
    }

}

src/test/java で以下のクラスでモックできました:

@Mock
@ApplicationScoped (1)
public class MockExternalService extends ExternalService {

    @Override
    public String service() {
        return "mock";
    }
}
1 @Mock ステレオタイプで宣言された @Dependent スコープをオーバーライドします。

代替品が src/main/java ではなく src/test/java ディレクトリーに存在することが重要です。そうでなければ、テスト以外も常に有効になってしまいます。

Note that at present this approach does not work with native image testing, as this would require the test alternatives to be baked into the native image.

11.2. QuarkusMock を使用したモッキング

io.quarkus.test.junit.QuarkusMock クラスは、通常のスコープ付きBeanを一時的にモックアウトするために使用することができます。 @BeforeAll メソッドでこのメソッドを使用した場合、モックは現在のクラスのすべてのテストに対して有効になりますが、test メソッドでこれを使用した場合、モックは現在のテストの間のみ有効になります。

この方法は、通常のスコープ付き CDI Bean(例: @ApplicationScoped , @RequestScoped など、 @Singleton@Dependent 以外の基本的にすべてのスコープ)に対して使用することができます。

使用例は次のようになります:

@QuarkusTest
public class MockTestCase {

    @Inject
    MockableBean1 mockableBean1;

    @Inject
    MockableBean2 mockableBean2;

    @BeforeAll
    public static void setup() {
        MockableBean1 mock = Mockito.mock(MockableBean1.class);
        Mockito.when(mock.greet("Stuart")).thenReturn("A mock for Stuart");
        QuarkusMock.installMockForType(mock, MockableBean1.class);  (1)
    }

    @Test
    public void testBeforeAll() {
        Assertions.assertEquals("A mock for Stuart", mockableBean1.greet("Stuart"));
        Assertions.assertEquals("Hello Stuart", mockableBean2.greet("Stuart"));
    }

    @Test
    public void testPerTestMock() {
        QuarkusMock.installMockForInstance(new BonjourGreeter(), mockableBean2); (2)
        Assertions.assertEquals("A mock for Stuart", mockableBean1.greet("Stuart"));
        Assertions.assertEquals("Bonjour Stuart", mockableBean2.greet("Stuart"));
    }

    @ApplicationScoped
    public static class MockableBean1 {

        public String greet(String name) {
            return "Hello " + name;
        }
    }

    @ApplicationScoped
    public static class MockableBean2 {

        public String greet(String name) {
            return "Hello " + name;
        }
    }

    public static class BonjourGreeter extends MockableBean2 {
        @Override
        public String greet(String name) {
            return "Bonjour " + name;
        }
    }
}
1 インジェクションされたインスタンスはここでは利用できないので、 installMockForType を使用します。このモックは両方のテストメソッドに使用されます。
2 私たちは installMockForInstance を使用して注入されたBeanを置き換えます。

Mockitoには依存しないことに注意してください。好きなモッキングライブラリを使うことができますし、必要な動作を提供するためにオブジェクトを手動でオーバーライドすることもできます。

@Inject を使用すると、インストールしたモックインスタンスへの CDI プロキシーを取得できます。これは、モックインスタンス自体が必要な Mockito.verify などのメソッドに渡すのには適していません。したがって、verify などのメソッドを呼び出す必要がある場合は、テストでモックインスタンスを保持するか、以下のように @InjectMock を使用する必要があります。

11.2.1. @InjectMock での更なる単純化

QuarkusMock で提供されている機能をベースに、Quarkusでは、 QuarkusMock でサポートされているBeanをモックするために Mockito を簡単に利用できるようにしています。この機能は、 quarkus-junit5-mockito 依存関係で利用可能な @io.quarkus.test.junit.mockito.InjectMock アノテーションを介して利用できます。

@InjectMock を使用すると、先ほどの例は次のように書くことができます:

@QuarkusTest
public class MockTestCase {

    @InjectMock
    MockableBean1 mockableBean1; (1)

    @InjectMock
    MockableBean2 mockableBean2;

    @BeforeEach
    public void setup() {
        Mockito.when(mockableBean1.greet("Stuart")).thenReturn("A mock for Stuart"); (2)
    }

    @Test
    public void firstTest() {
        Assertions.assertEquals("A mock for Stuart", mockableBean1.greet("Stuart"));
        Assertions.assertEquals(null, mockableBean2.greet("Stuart")); (3)
    }

    @Test
    public void secondTest() {
        Mockito.when(mockableBean2.greet("Stuart")).thenReturn("Bonjour Stuart"); (4)
        Assertions.assertEquals("A mock for Stuart", mockableBean1.greet("Stuart"));
        Assertions.assertEquals("Bonjour Stuart", mockableBean2.greet("Stuart"));
    }

    @ApplicationScoped
    public static class MockableBean1 {

        public String greet(String name) {
            return "Hello " + name;
        }
    }

    @ApplicationScoped
    public static class MockableBean2 {

        public String greet(String name) {
            return "Hello " + name;
        }
    }
}
1 @InjectMock により、モックがテストクラスのテストメソッドに存在することになり、利用可能になります (他のテストクラスはこの影響を受け ません )。
2 クラスのすべてのテストメソッドに対して mockableBean1 が設定されています。
3 mockableBean2 のモックが設定されていないので、デフォルトの Mockito レスポンスを返します。
4 このテストでは、 mockableBean2 が設定されているので、設定されたレスポンスを返します。

上のテストは @InjectMock の機能を示すのには良いですが、実際のテストを上手く表してはいません。実際のテストでは、ほとんどの場合、モックを設定し、モックされたBeanを使用するBeanをテストします。以下に例を示します:

@QuarkusTest
public class MockGreetingServiceTest {

    @InjectMock
    GreetingService greetingService;

    @Test
    public void testGreeting() {
        when(greetingService.greet()).thenReturn("hi");
        given()
                .when().get("/greeting")
                .then()
                .statusCode(200)
                .body(is("hi")); (1)
    }

    @Path("greeting")
    public static class GreetingResource {

        final GreetingService greetingService;

        public GreetingResource(GreetingService greetingService) {
            this.greetingService = greetingService;
        }

        @GET
        @Produces("text/plain")
        public String greet() {
            return greetingService.greet();
        }
    }

    @ApplicationScoped
    public static class GreetingService {
        public String greet(){
            return "hello";
        }
    }
}
1 greetingService をモックとして設定したので、 GreetingService Beanを使用する GreetingResource は、通常の GreetingService Beanのレスポンスの代わりにモックされたレスポンスを取得します。

By default, the @InjectMock annotation can be used for any normal CDI scoped bean (e.g. @ApplicationScoped, @RequestScoped). Mocking @Singleton beans can be performed by setting the convertScopes property to true (such as @InjectMock(convertScopes = true). This will convert the @Singleton bean to an @ApplicationScoped bean for the test.

これは高度なオプションと見なされ、Bean のスコープを変更することで引き起こされる結果を完全に理解している場合にのみ実行する必要があります。

11.2.2. @InjectSpy で、モックの代わりにスパイを使用する

InjectMock で提供されている機能をベースに、 QuarkusMock でサポートされているBeanをスパイするために Mockito を簡単に利用できるようにしました。この機能は、 quarkus-junit5-mockito 依存関係で利用可能な @io.quarkus.test.junit.mockito.InjectSpy アノテーションを介して利用できます。

テストを行う際に、特定の論理パスが取られたかどうかを確認するだけで済む場合もありますし、Spied クローン上で残りのメソッドを実行している間に、1つのメソッドのレスポンスをスタブアウトするだけで済む場合もあります。Spy パーシャル モックの詳細については Mockito のドキュメントを参照してください。いずれの場合も、オブジェクトの Spy が望ましいでしょう。 @InjectSpy を使用して、先ほどの例は次のように書くことができます。

@QuarkusTest
public class SpyGreetingServiceTest {

    @InjectSpy
    GreetingService greetingService;

    @Test
    public void testDefaultGreeting() {
        given()
                .when().get("/greeting")
                .then()
                .statusCode(200)
                .body(is("hello"));

        Mockito.verify(greetingService, Mockito.times(1)).greet(); (1)
    }

    @Test
    public void testOverrideGreeting() {
        when(greetingService.greet()).thenReturn("hi"); (2)
        given()
                .when().get("/greeting")
                .then()
                .statusCode(200)
                .body(is("hi")); (3)
    }

    @Path("greeting")
    public static class GreetingResource {

        final GreetingService greetingService;

        public GreetingResource(GreetingService greetingService) {
            this.greetingService = greetingService;
        }

        @GET
        @Produces("text/plain")
        public String greet() {
            return greetingService.greet();
        }
    }

    @ApplicationScoped
    public static class GreetingService {
        public String greet(){
            return "hello";
        }
    }
}
1 値をオーバーライドするのではなく、 GreetingService の greet メソッドがこのテストで呼び出されたことを確認したいだけです。
2 ここでは、"hello"の代わりに"hi"を返すようにSpyに指示しています。 GreetingResourceGreetingService から挨拶を要求するとき、通常の GreetingService Bean のレスポンスの代わりにモックされたレスポンスを取得します。
3 私たちは、スパイからのモックされた応答を得ることを検証しています。

11.2.3. @InjectMock との併用 @RestClient

@RegisterRestClient は、実行時に rest-client の実装を登録しています。Beanは通常のスコープである必要があるため、インターフェイスに @ApplicationScoped を付与する必要があります。

@Path("/")
@ApplicationScoped
@RegisterRestClient
public interface GreetingService {

    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    String hello();
}

テストクラスの例です:

@QuarkusTest
public class GreetingResourceTest {

    @InjectMock
    @RestClient (1)
    GreetingService greetingService;

    @Test
    public void testHelloEndpoint() {
        Mockito.when(greetingService.hello()).thenReturn("hello from mockito");

        given()
          .when().get("/hello")
          .then()
             .statusCode(200)
             .body(is("hello from mockito"));
    }

}
1 この注入ポイントが RestClient のインスタンスを使用することを意味していることを示します。

11.3. Panache でのモック

quarkus-hibernate-orm-panachequarkus-mongodb-panache のエクステンションを使っている場合は、Hibernate ORM と Panache モック および MongoDB と Panache モック のドキュメントをチェックして、データアクセスをモックする最も簡単な方法を確認してください。

12. セキュリティーのテスト

Quarkus Securityを使用している場合、アプリケーションのセキュリティー機能を簡単にテストする方法については、セキュリティーのテスト のセクションをご覧ください。

13. Quarkus アプリケーション起動前のサービス開始

非常に一般的なニーズは、Quarkusアプリケーションがテストを開始する前に、Quarkusアプリケーションに依存するいくつかのサービスを開始することです。このニーズに対応するために、Quarkusでは、 @io.quarkus.test.common.QuarkusTestResourceio.quarkus.test.common.QuarkusTestResourceLifecycleManager を提供します。

テストスイート内のテストに @QuarkusTestResource のアノテーションを付けるだけで、Quarkus は、テストが実行される前に対応する QuarkusTestResourceLifecycleManager を実行します。テストスイートは、複数の @QuarkusTestResource アノテーションを自由に利用することもできます。この場合、対応するすべての QuarkusTestResourceLifecycleManager オブジェクトがテストの前に実行されます。複数のテストリソースを使用する場合、それらを同時に開始できます。そのためには、@QuarkusTestResource(parallel = true) を設定する必要があります。

テストリソースは、テストクラスまたはカスタムプロファイルで定義されている場合でもグローバルです。つまり、重複を削除しても、すべてのテストですべてアクティブになります。単一のテストクラスまたはテストプロファイルに限定してテストリソースを有効にする場合は、@QuarkusTestResource(restrictToAnnotatedClass = true) を使用できます。

Quarkus provides a few implementations of QuarkusTestResourceLifecycleManager out of the box (see io.quarkus.test.h2.H2DatabaseTestResource which starts an H2 database, or io.quarkus.test.kubernetes.client.KubernetesServerTestResource which starts a mock Kubernetes API server), but it is common to create custom implementations to address specific application needs. Common cases include starting docker containers using Testcontainers (an example of which can be found here), or starting a mock HTTP server using Wiremock (an example of which can be found here).

13.1. テストクラスの変更

テストクラスに何かを注入する必要があるカスタム の QuarkusTestResourceLifecycleManager を作成する場合、inject メソッドを使用できます。たとえば、次のようなテストがある場合:

@QuarkusTest
@QuarkusTestResource(MyWireMockResource.class)
public class MyTest {

    @InjectWireMock // this a custom annotation you are defining in your own application
    WireMockServer wireMockServer;

    @Test
    public someTest() {
        // control wiremock in some way and perform test
    }
}

次のコードスニペットの inject メソッドに示すように、MyWireMockResourcewireMockServer フィールドを注入させることができます。

public class MyWireMockResource implements QuarkusTestResourceLifecycleManager {

    WireMockServer wireMockServer;

    @Override
    public Map<String, String> start() {
        wireMockServer = new WireMockServer(8090);
        wireMockServer.start();

        // create some stubs

        return Map.of("some.service.url", "localhost:" + wireMockServer.port());
    }

    @Override
    public synchronized void stop() {
        if (wireMockServer != null) {
            wireMockServer.stop();
            wireMockServer = null;
        }
    }

    @Override
    public void inject(TestInjector testInjector) {
        testInjector.injectIntoFields(wireMockServer, new TestInjector.AnnotatedAndMatchesType(InjectWireMock.class, WireMockServer.class));
    }
}
テストクラスへのこの注入は CDI の制御下になく、CDI がテストクラスへの必要な注入を実行した後に発生することは言及に値します。

13.2. アノテーションベースのテストリソース

アノテーションを使用して有効化および設定されたテストリソースを作成することができます。これは、テストリソースの有効化と設定に使用されるアノテーション に @QuarkusTestResource を配置することで可能になります。

たとえば、これは @WithKubernetesTestServer アノテーションを定義します。これは、テストで KubernetesServerTestResource をアクティブ化するために使用できますが、アノテーションが付けられたテストクラスに限定されます。これは QuarkusTestProfile テストプロファイルに配置することもできます。

@QuarkusTestResource(KubernetesServerTestResource.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface WithKubernetesTestServer {
    /**
     * Start it with HTTPS
     */
    boolean https() default false;

    /**
     * Start it in CRUD mode
     */
    boolean crud() default true;

    /**
     * Port to use, defaults to any available port
     */
    int port() default 0;
}

The KubernetesServerTestResource class has to implement the QuarkusTestResourceConfigurableLifecycleManager interface in order to be configured using the previous annotation:

public class KubernetesServerTestResource
        implements QuarkusTestResourceConfigurableLifecycleManager<WithKubernetesTestServer> {

    private boolean https = false;
    private boolean crud = true;
    private int port = 0;

    @Override
    public void init(WithKubernetesTestServer annotation) {
        this.https = annotation.https();
        this.crud = annotation.crud();
        this.port = annotation.port();
    }

    // ...
}

14. ハング検出

@QuarkusTest は、予期しないハングを診断するために使用できるハング検出をサポートしています。指定された時間内に進捗がない場合 (つまり、JUnit コールバックが呼び出されない場合)、Quarkus はスタックトレースをコンソールに出力して、ハングの診断を助けます。このタイムアウトのデフォルト値は 10 分です。

これ以上のアクションは実行されず、テストは通常どおり (通常は CI がタイムアウトするまで) 続行されますが、出力されたスタックトレースは、ビルドが失敗した理由を診断するのに役立ちます。このタイムアウトは、quarkus.test.hang-detection-timeout システムプロパティーで制御できます (これは application.properties でも設定できますが、Quarkus が起動するまで読み取られないため、Quarkus の起動タイムアウトはデフォルトの 10 分です)。

15. ネイティブ実行可能ファイルテスト

@QuarkusIntegrationTest を使用してネイティブ実行可能ファイルをテストすることも可能です。これは、テストに注入すること (そして、ネイティブ実行可能ファイルは別の非 JVM プロセスで実行されることーこれは実際には可能ではありません) を除いて、このガイドで述べたすべての機能をサポートしています。

これについては、ネイティブ実行可能ファイルガイド で説明されています。

16. Using @QuarkusIntegrationTest

@QuarkusIntegrationTest は、Quarkus ビルドによって生成されたアーティファクトを起動およびテストするために使用する必要があり、jar (タイプを問わず)、ネイティブイメージ、またはコンテナーイメージのテストをサポートします。簡単に言えば、Quarkus ビルド (mvn package または gradle build) の結果が jar である場合、その jar は java -jar …​ として起動され、それに対してテストが実行されることを意味します。ネイティブイメージがビルドされた場合、アプリケーションは ./application …​ として起動され、実行中のアプリケーションに対してテストが実行されます。最後に、ビルド中に ( quarkus-container-image-jib または quarkus-container-image-docker エクステンションを含め、 quarkus.container-image.build=true プロパティーを設定することで) コンテナーイメージが作成された場合)、コンテナーが作成されて実行されます (これには、docker 実行可能ファイルが存在する必要があります)。

@NativeImageTest の場合と同様に、これは同じセットの機能をサポートし、同じ制限があるブラックボックステストです。

As a test annotated with @QuarkusIntegrationTest tests the result of the build, it should be run as part of the integration test suite - i.e. by setting -DskipITs=false if using Maven or the quarkusIntTest task if using Gradle. These tests will not work if run in the same phase as @QuarkusTest as Quarkus has not yet created the final artifact.

The pom.xml file contains:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
            <configuration>
                <systemPropertyVariables>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                    <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    <maven.home>${maven.home}</maven.home>
                </systemPropertyVariables>
            </configuration>
        </execution>
    </executions>
</plugin>

This instructs the failsafe-maven-plugin to run integration-test.

Then, open the src/test/java/org/acme/quickstart/GreetingResourceIT.java. It contains:

package org.acme.quickstart;


import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest (1)
public class GreetingResourceIT extends GreetingResourceTest { (2)

    // Run the same tests

}
1 Use another test runner that starts the application from the native file before the tests. The executable is retrieved by the Failsafe Maven Plugin.
2 We extend our previous tests as a convenience, but you can also implement your tests.

More information can be found in the Testing the native executable Guide.

16.1. コンテナーの起動

@QuarkusIntegrationTest によってコンテナーが起動されると (アプリケーションは`quarkus.container-image.build` が true に設定されているため)、コンテナーは予測可能なコンテナーネットワーク上で起動されます。これにより、アプリケーションをサポートするためにサービスを起動する必要がある統合テストの作成が容易になります。これは、@QuarkusIntegrationTest が、Dev Services を介して起動されたコンテナーでそのまま機能することを意味しますが、追加のコンテナーを起動する QuarkusTestLifecycleManager リソースを使用して有効化することも意味します。これは、QuarkusTestLifecycleManagerio.quarkus.test.common.DevServicesContext.ContextAware を実装することで実現できます。以下は、その簡単な例です。

テストするリソースを実行しているコンテナー (たとえば Testcontainers を介した PostgreSQL) には、コンテナーのネットワークから IP アドレスが割り当てられます。コンテナーのネットワークからの「パブリック」IP と「マップされていない」ポート番号を使用してサービスに接続します。Testcontainers ライブラリーは通常、コンテナーネットワークを尊重せずに接続文字列を返すため、コンテナーネットワーク上のコンテナーの IP と_マップされていない_ポート番号を使用して Quarkus に正しい接続文字列を提供するには、追加のコードが必要です。

次の例は PostgreSQL での使用法を示していますが、このアプローチはすべてのコンテナーに適用できます。

import io.quarkus.test.common.DevServicesContext;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;

import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.PostgreSQLContainer;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class CustomResource implements QuarkusTestResourceLifecycleManager, DevServicesContext.ContextAware {

    private Optional<String> containerNetworkId;
    private JdbcDatabaseContainer container;

    @Override
    public void setIntegrationTestContext(DevServicesContext context) {
        containerNetworkId = context.containerNetworkId();
    }

    @Override
    public Map<String, String> start() {
        // start a container making sure to call withNetworkMode() with the value of containerNetworkId if present
        container = new PostgreSQLContainer<>("postgres:latest").withLogConsumer(outputFrame -> {});

        // apply the network to the container
        containerNetworkId.ifPresent(container::withNetworkMode);

        // start container before retrieving its URL or other properties
        container.start();

        String jdbcUrl = container.getJdbcUrl();
        if (containerNetworkId.isPresent()) {
            // Replace hostname + port in the provided JDBC URL with the hostname of the Docker container
            // running PostgreSQL and the listening port.
            jdbcUrl = fixJdbcUrl(jdbcUrl);
        }

        // return a map containing the configuration the application needs to use the service
        return ImmutableMap.of(
            "quarkus.datasource.username", container.getUsername(),
            "quarkus.datasource.password", container.getPassword(),
            "quarkus.datasource.jdbc.url", jdbcUrl);
    }

    private String fixJdbcUrl(String jdbcUrl) {
        // Part of the JDBC URL to replace
        String hostPort = container.getHost() + ':' + container.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT);

        // Host/IP on the container network plus the unmapped port
        String networkHostPort =
            container.getCurrentContainerInfo().getConfig().getHostName()
            + ':'
            + PostgreSQLContainer.POSTGRESQL_PORT;

        return jdbcUrl.replace(hostPort, networkHostPort);
    }

    @Override
    public void stop() {
        // close container
    }
}

このドキュメントの対応するセクションで説明されているように、CustomResource@QuarkusTestResource を使用して @QuarkusIntegrationTest でアクティブ化されます。

16.2. 実行中のアプリケーションに対する実行

この機能は実験的なものと見なされており、Quarkus の将来のバージョンで変更される可能性があります。

@QuarkusIntegrationTest は、アプリケーションのすでに実行中のインスタンスに対するテストの実行をサポートします。これは、テストの実行時に quarkus.http.test-host システムプロパティーを設定することで実現できます。

次の Maven コマンドはその使用例で、@ QuarkusIntegrationTest を強制的に実行し、http://1.2.3.4:4321 からアクセスできます。

./mvnw verify -Dquarkus.http.test-host=1.2.3.4 -Dquarkus.http.test-port=4321

17. @QuarkusTest と他のタイプのテストを混合

@QuarkusTest でアノテーションが付けられたテストと、@QuarkusDevModeTest@QuarkusProdModeTest@QuarkusUnitTest のいずれかでアノテーションが付けられたテストを、1 回の実行 (たとえば、1 回の Maven Surefire プラグインの実行) で混合することはできません。ただsじょ。後者の 3 つは共存できます。

この制限の理由は、@QuarkusTest がテスト実行の期間全体にわたって Quarkus サーバーを起動するため、他のテストが独自の Quarkus サーバーを起動できないようにするためです。

この制限を緩和するために、@QuarkusTest アノテーションは JUnit5 @Tag を定義します: io.quarkus.test.junit.QuarkusTest 。このタグを使用して、特定の実行 で @QuarkusTest テストを分離できます。以下は Maven Surefire プラグインを使用した例です。

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <executions>
        <execution>
            <id>default-test</id>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <excludedGroups>io.quarkus.test.junit.QuarkusTest</excludedGroups>
            </configuration>
        </execution>
        <execution>
            <id>quarkus-test</id>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <groups>io.quarkus.test.junit.QuarkusTest</groups>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <systemProperties>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
        </systemProperties>
    </configuration>
</plugin>

18. IDE から @QuarkusTest を実行する

ほとんどの IDE では、選択したクラスを JUnit テストとして直接実行できるようになっています。そのためには、選択した IDE の設定でいくつかのプロパティーを設定する必要があります。

  • java.util.logging.manager (ロギングガイド を参照)

  • maven.home (${maven.home}/conf/settings.xml にカスタム設定がある場合のみ、Maven ガイド` を参照)

  • maven.settings (カスタム版の settings.xml ファイルをテストに使用する場合)

18.1. Eclipse の個別 JRE の定義

現在の"Installed JRE"定義を新しい定義にコピーし、新しいVMの引数としてプロパティーを追加します:

  • -Djava.util.logging.manager=org.jboss.logmanager.LogManager

  • -Dmaven.home=<path-to-your-maven-installation>

このJRE定義をQuarkusプロジェクトのターゲットランタイムとして使用すると、「Run as JUnit」設定に回避策が適用されます。

18.2. VSCode "run with" 設定

プロジェクトディレクトリーやワークスペースのルートにある settings.json には、テスト設定で次の回避策が必要です。

"java.test.config": [
    {
        "name": "quarkusConfiguration",
        "vmargs": [ "-Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dmaven.home=<path-to-your-maven-installation> ..." ],
        ...
    },
  ...
]

18.3. IntelliJ IDEA JUnit template

Nothing needed in IntelliJ IDEA because the IDE will pick the systemPropertyVariables from the surefire plugin configuration in pom.xml.

19. Dev Services のテスト

By default, tests should just work with Dev Services, however from some use cases you may need access to the automatically configured properties in your tests.

これは、@QuarkusTest または @QuarkusIntegrationTest に直接注入できる io.quarkus.test.common.DevServicesContext を使用して行うことができます。タイプ DevServicesContext のフィールドを定義するだけで、自動的に注入されます。これを使用して、設定されている任意のプロパティーを取得できます。通常、これは、テスト自体からリソースに直接接続するために使用されます。たとえば、kafka に接続して、テスト対象のアプリケーションにメッセージを送信するために使用されます。

io.quarkus.test.common.DevServicesContext.ContextAware を実装するオブジェクトへの注入もサポートされています。io.quarkus.test.common.DevServicesContext.ContextAware を実装するフィールドがある場合、Quarkus は` setIntegrationTestContext` メソッドを呼び出して、コンテキストをこのオブジェクトに渡します。これにより、クライアントロジックをユーティリティークラスにカプセル化できます。

QuarkusTestResourceLifecycleManager implementations can also implement ContextAware to get access to these properties, which allows you to set up the resource before Quarkus starts (e.g. configure a KeyCloak instance, add data to a database etc).

アプリケーションをコンテナーとしてランチャーにする @QuarkusIntegrationTest テストの場合、io.quarkus.test.common.DevServicesContext は、アプリケーションコンテナーが起動されたコンテナーネットワークの ID へのアクセスも提供します (containerNetworkId メソッドを使用)。これは、アプリケーションが通信する追加のコンテナーを起動する必要がある QuarkusTestResourceLifecycleManager で使用できます。