如何将 Quarkus 中的测试容器连接到 DevServices 的 Docker 网络?

How can I connect a test container in Quarkus to the Docker network of DevServices?

在我的@QuarkusIntegrationTest中我想使用一个MockServer testcontainer that simulates the responses to requests from my application. To start the MockServer I use testcontainers. The application uses http://localhost:port,其中端口是mockserverContainer.getMappedPort()。一切正常。

当我使用 -Dquarkus.container-image.build=true 测试应用程序时,出现以下问题:Quarkus 创建一个 Docker 网络并将容器与应用程序和 MongoDb 测试容器连接到此通过 DevServices 联网。我也想将 MockServer 测试容器带入这个网络,但我做不到。 Network.SHARED 测试中可用的网络不是 Quarkus 用于 DevServices 的网络。当然,我可以使用主机的 IP 地址从正在测试的应用程序访问 MockServer,这会使构建脚本复杂化,因为主机的 IP 地址在每个环境中都不容易确定。

有什么方法可以让测试容器连接到 Quarkus DevService 使用的 Docker 网络?

(Quarkus 版本 2.3.0)

以下示例使用 -Dquarkus.container-image.build=false 选项,即如果应用程序本身不在容器中 运行。

@QuarkusIntegrationTest
@Testcontainers
public class JobTest {

    @Container
    public static MockServerContainer serverContainer = new MockServerContainer()

    @BeforeAll
    public static initMockServer() {
      String json = ...
      new MockServerClient(serverContainer.getHost(), serverContainer.getServerPort())
          .when(request()
              .withMethod("GET")
              .withPath(".*"))
          .respond(response()
              .withStatusCode(Response.Status.OK.getStatusCode())
              .withHeader(CONTENT_TYPE, MediaType.APPLICATION_JSON)
              .withBody(json));
    }

    @Test
    @DisplayName("import recipe from website")
    public void importRecipe() {
        // The URL that the application wants to get data from. Is simulated by the MockServer. 
        var recipeUrl = String.format("http://localhost:%d/lasagne.html", serverContainer.getServerPort());
        // The URL of the application that triggered the import function. 
        var jobUrl = String.format("http://localhost:%s/job", System.getProperty("quarkus.http.port"));
        RestAssured
                .given()
                .body(createJob(recipeUrl))
                .contentType(ContentType.JSON)
                .when()
                .post(jobUrl)
                .then()
                .statusCode(Response.Status.CREATED.getStatusCode())
                .header("Location", r -> equalTo(url + "/" + r.path("jobId")));
    }
}

从 Quarkus 2.5 开始,您将能够执行以下操作:

public class CustomResource implements QuarkusTestResourceLifecycleManager, DevServicesContext.ContextAware {

    private Optional<String> containerNetworkId = Optional.empty(); 

    @Override
    public Map<String, String> start() {
        // start a container here using containerNetworkId
        return someMap;
    }

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


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

你的测试将是:

@QuarkusIntegrationTest
@QuarkusTestResource(CustomResource.class)
public class JobTest {
  

   ...


}

有关详细信息,请参阅 this