Spring Boot TestContainers 映射的端口只能在容器启动后获取
Posted
技术标签:
【中文标题】Spring Boot TestContainers 映射的端口只能在容器启动后获取【英文标题】:Spring Boot TestContainers Mapped port can only be obtained after the container is started 【发布时间】:2020-08-20 19:56:17 【问题描述】:我正在尝试将使用 TestContainers 库的自动化测试添加到我的 Spring Boot 项目中
这是我的测试类来测试我的 jpa 存储库:
package com.ubm.mfi.repo;
import com.ubm.mfi.domain.MasterFileIndexRow;
import org.junit.ClassRule;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
@ContextConfiguration(initializers = MasterFileIndexRowRepoTest.Initializer.class )
public class MasterFileIndexRowRepoTest
@ClassRule
public static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:latest");
@Autowired
private MasterFileIndexRowRepo masterFileIndexRowRepo;
// write test cases here
@Test
public void whenFindAllRows_thenSizeIsGreaterThanZero()
// when
List<MasterFileIndexRow> rows = masterFileIndexRowRepo.findAll();
// then
assertThat(rows.size())
.isGreaterThan(0);
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext)
TestPropertyValues
.of("spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
"spring.datasource.username=" + postgreSQLContainer.getUsername(),
"spring.datasource.password=" + postgreSQLContainer.getPassword())
.applyTo(configurableApplicationContext.getEnvironment());
这是我的 build.gradle 中的依赖项
testCompile "org.testcontainers:testcontainers:1.14.1"
testCompile "org.testcontainers:postgresql:1.14.1"
运行测试时出现此错误: Caused by: java.lang.IllegalStateException: Mapped port can only be obtained after the container is started
据我所见,容器应该在开始测试时启动,有人知道我缺少什么吗?
【问题讨论】:
这个错误可能是由另一个错误引起的 -> github.com/testcontainers/testcontainers-java/issues/3609 检查你的日志中是否有“Could not connect to Ryuk at localhost:49154”。 【参考方案1】:您正在尝试将PostgresSQLContainer
用作JUnit ClassRule
,但您使用@ExtendWith
似乎表明您正在使用不支持JUnit 4 规则的JUnit 5 / Jupiter。
改用 JUnit 5 集成的 Testcontainers:https://www.testcontainers.org/test_framework_integration/junit_5/
【讨论】:
也可以使用 JDBC 集成:testcontainers.org/modules/databases/jdbc以上是关于Spring Boot TestContainers 映射的端口只能在容器启动后获取的主要内容,如果未能解决你的问题,请参考以下文章
使用 Testcontainer 进行 Spring 集成测试 - 数据库在应用程序之后启动
Spring boot、ElasticSearch 和 TestContainers 集成测试。拒绝连接
Spring JUnit 5 ExtendWith TestContainer
如何运行自定义 docker 镜像 testContainer