如何在Spring Boot上解决org.testcontainers.containers.ContainerFetchException?

问题描述

我正在为我的Spring Boot应用程序开发一些集成测试。我正在使用testcontainers来创建MongoDB码头工人形象。到目前为止,我的代码

ContainerListener.java 类:

公共类ContainerListener实现TestListener {

@ClassRule
public static Network sharednetwork = Network.newNetwork();

@ClassRule
public static GenericContainer mongoDBContainer = new GenericContainer("mongo:3.2.4").withNetwork(sharednetwork)
        .withNetworkAliases("mongo").withExposedPorts(27017);

public static MockServerContainer mockServerContainer = new MockServerContainer().withNetwork(sharednetwork)
        .withNetworkAliases("mockserver").withExposedPorts(1080);

public static int getMockPort() {
    return mockServerContainer.getMappedPort(1080);
}

public static int getMongoPort() {
    return mongoDBContainer.getMappedPort(27017);
}

public static void runAll() {
    List.of(mongoDBContainer,mockServerContainer).forEach(e -> e.start());
}

public static void stopAll() {
    List.of(mongoDBContainer,mockServerContainer).forEach(e -> e.stop());
}

}

SomeControllerIntegrationTest.java 类:

import io.restassured.RestAssured;
import io.restassured.parsing.Parser;
import org.junit.jupiter.api.Afterall;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;

public class ratingControllerIntegrationTest {

    @BeforeAll
    public static void setuo() {
        ContainerListener.runAll();

    }

    @Afterall
    public static void tearDown() {
        ContainerListener.stopAll();
    }

    @Test
    public void detailstest() throws Exception {
        RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
        RestAssured.defaultParser = Parser.JSON;

        given().log().all().when().get("http://localhost:8080/actuator/info/").then().log().all()
                .statusCode(200);
    }

}

尽管运行测试后,我收到以下错误

org.testcontainers.containers.ContainerLaunchException: Container startup Failed

Caused by: org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=mongo:3.2.4,imagePullPolicy=DefaultPullPolicy())
    at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1279)
    at org.testcontainers.containers.GenericContainer.logger(GenericContainer.java:613)
    at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:320)
    ... 58 more
Caused by: java.lang.IllegalStateException: Can not connect to Ryuk at localhost:32770
    at org.testcontainers.utility.ResourceReaper.start(ResourceReaper.java:176)
    at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:168)
    at org.testcontainers.LazyDockerClient.getDockerClient(LazyDockerClient.java:14)
    at org.testcontainers.LazyDockerClient.listimagesCmd(LazyDockerClient.java:12)
    at org.testcontainers.images.LocalImagesCache.maybeInitCache(LocalImagesCache.java:68)
    at org.testcontainers.images.LocalImagesCache.get(LocalImagesCache.java:32)
    at org.testcontainers.images.AbstractimagePullPolicy.shouldPull(AbstractimagePullPolicy.java:18)
    at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:59)
    at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:26)
    at org.testcontainers.utility.LazyFuture.getResolvedValue(LazyFuture.java:20)
    at org.testcontainers.utility.LazyFuture.get(LazyFuture.java:27)
    at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1277)
    ... 60 more

解决方法

如果您还没有看到:https://github.com/testcontainers/testcontainers-java/issues/3166

github用户@bsideup概述了三个选项。当然,这仅适用于您是使用Docker for Mac的Mac用户。

  • 使用包含该修复程序的Testcontainers 1.15.0-rc2
  • 在Mac 2.4.0的Docker中禁用gRPC FUSE
  • 降级到适用于Mac 2.3.x的Docker

这个(禁用gRPC)为我解决了这个问题,因此我将其作为参考。根据您的工作流程,不使用gRPC FUSE可能会产生重大影响。因此,您最好检查一下是否还可以,或者将其降级为适用于Mac 2.3.x的Docker。我没有选择第一个选项,因为它似乎并没有停止容器,这对我来说是最糟糕的选择。