Spring Boot 3 + Testcontainers:在没有明确错误信息的情况下,集成测试被忽略
我在用 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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。