Spring Boot 3 + Testcontainers:在没有明确错误信息的情况下,集成测试被忽略

后端开发 2026-07-09

我在用 MySQLContainer@ServiceConnection 进行集成测试,但JUnit只是把它们标记为“忽略/跳过”,我不知道该怎么做。

IT类:

@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ArtistControllerIT {


    @Autowired
    private TestRestTemplate testRestTemplate;

    @Container
    @ServiceConnection
    private static final org.testcontainers.mysql.MySQLContainer container = new MySQLContainer("mysql:8.0");

    @LocalServerPort
    private int port;

    @Autowired
    private ArtistRepository artistRepository;


    @Test
    @DisplayName("List returns list of artist inside page object when successful")
    void list_ReturnsListOfArtistInsidePageObjet_WhenSuccessful() {

        Artist saved = artistRepository.save(ArtistCreator.createArtistToBeSaved());

        PageableResponse<Artist> artistPage = testRestTemplate.exchange("/artists/list-artists", HttpMethod.GET, null, new ParameterizedTypeReference<PageableResponse<Artist>>() {
        }).getBody();

        org.assertj.core.api.Assertions.assertThat(artistPage).isNotNull();
        org.assertj.core.api.Assertions.assertThat(artistPage.getContent()).hasSize(1);
        org.assertj.core.api.Assertions.assertThat(artistPage.getContent().get(0).getName()).isEqualTo(saved.getName());
    }



    @Test
    @DisplayName("Should return an artist dto by id when found one")
    void shouldReturnAnArtist_WhenPassedId() {

        Artist saved = artistRepository.save(ArtistCreator.createValidArtist());

        testRestTemplate.exchange("/artists", HttpMethod.GET, null,  saved.getClass(), saved.getId());

        org.junit.jupiter.api.Assertions.assertEquals(1L, saved.getId(), "ID SHOULD BE 1");
    }
}

依赖项:

<properties>
    <java.version>25</java.version>
    <org.mapstruct.version>1.6.3</org.mapstruct.version>
</properties>

<dependencies>
    <!-- Source: https://mvnrepository.com/artifact/org.jspecify/jspecify -->
    <dependency>
        <groupId>org.jspecify</groupId>
        <artifactId>jspecify</artifactId>
        <version>1.0.0</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-testcontainers</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
    <!-- Source: https://mvnrepository.com/artifact/org.testcontainers/junit-jupiter -->
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>1.20.5</version>
        <scope>test</scope>
    </dependency>
    <!-- Source: https://mvnrepository.com/artifact/org.testcontainers/postgresql -->
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>testcontainers-mysql</artifactId>
        <version>2.0.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
</dependencies>

application-test.yml:

spring:
  datasource:
    url: jdbc:tc:mysql:8.4:///testdb
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver

当我在终端运行docker-compose up时,能工作。但测试连起都没开始。在日志中,我看到:

java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration
    at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$getFirstValidStrategy$7(DockerClientProviderStrategy.java:274)
    at java.base/java.util.Optional.orElseThrow(Optional.java:403)
    at org.testcontainers.dockerclient.DockerClientProviderStrategy.getFirstValidStrategy(DockerClientProviderStrategy.java:265)
    at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:154)
    at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:196)
    at org.testcontainers.DockerClientFactory$1.getDockerClient(DockerClientFactory.java:108)
    at com.github.dockerjava.api.DockerClientDelegate.authConfig(DockerClientDelegate.java:109)
    at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:321)

Suppressed: org.testcontainers.containers.ContainerFetchException: Can't get Docker image: RemoteDockerImage(imageName=mysql:8.4, imagePullPolicy=DefaultPullPolicy(), imageNameSubstitutor=org.testcontainers.utility.ImageNameSubstitutor$LogWrappedImageNameSubstitutor@44cb460e) at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1364) at org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory.createSource(ServiceConnectionContextCustomizerFactory.java:89) at org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory.lambda$collectSources$0(ServiceConnectionContextCustomizerFactory.java:64) at org.springframework.core.annotation.TypeMappedAnnotations$AggregatesSpliterator.tryAdvance(TypeMappedAnnotations.java:610) at org.springframework.core.annotation.TypeMappedAnnotations$AggregatesSpliterator.tryAdvance(TypeMappedAnnotations.java:577) at java.base/java.util.Spliterator.forEachRemaining(Spliterator.java:332) at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:803) at org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory.lambda$collectSources$1(ServiceConnectionContextCustomizerFactory.java:64) at org.springframework.util.ReflectionUtils.doWithLocalFields(ReflectionUtils.java:691) at org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory.collectSources(ServiceConnectionContextCustomizerFactory.java:61) at org.springframework.boot.testcontainers.service.connection.ServiceConnectionContextCustomizerFactory.createContextCustomizer(ServiceConnectionContextCustomizerFactory.java:53) at org.springframework.test.context.support.AbstractTestContextBootstrapper.getContextCustomizers(AbstractTestContextBootstrapper.java:360) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:332) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildDefaultMergedContextConfiguration(AbstractTestContextBootstrapper.java:267) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:215) at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:108) at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.buildTestContext(SpringBootTestContextBootstrapper.java:111) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:142) at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:126) at org.springframework.test.context.junit.jupiter.SpringExtension.getTestContextManager(SpringExtension.java:362) at org.springframework.test.context.junit.jupiter.SpringExtension.afterAll(SpringExtension.java:139) ... 1 more
Caused by: java.lang.IllegalStateException: Previous attempts to find a Docker environment failed. Will not retry. Please see logs and check configuration at org.testcontainers.dockerclient.DockerClientProviderStrategy.getFirstValidStrategy(DockerClientProviderStrategy.java:229) at org.testcontainers.DockerClientFactory.getOrInitializeStrategy(DockerClientFactory.java:154) at org.testcontainers.DockerClientFactory.client(DockerClientFactory.java:196) at org.testcontainers.images.LocalImagesCache.get(LocalImagesCache.java:31) at org.testcontainers.images.AbstractImagePullPolicy.shouldPull(AbstractImagePullPolicy.java:18) at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:79) at org.testcontainers.images.RemoteDockerImage.resolve(RemoteDockerImage.java:35) at org.testcontainers.utility.LazyFuture.getResolvedValue(LazyFuture.java:20) at org.testcontainers.utility.LazyFuture.get(LazyFuture.java:41) at org.testcontainers.containers.GenericContainer.getDockerImageName(GenericContainer.java:1362) ... 21 more

解决方案

日志中你可以看到: Can't get Docker image: RemoteDockerImage(imageName=mysql:8.4 ... 这意味着它无法获取到正确的Docker镜像,原因是镜像名称或版本不正确。

你可以把代码改成如下所示,并确保提供镜像名称和版本:

new MySQLContainer<>("mysql:latest")

或者使用

docker image ls

来查看你在Docker中已有的镜像列表,并核实所需镜像是否已下载。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章