Spring Boot单元测试用嵌入式PostgreSQL报错检索Docker如何解决?
问题原因
你当前使用的@AutoConfigureEmbeddedDatabase注解默认关联zonky嵌入式PostgreSQL实现,该实现的新版本默认优先采用Testcontainers方案启动PostgreSQL实例,因此会自动检索本地Docker环境,这就是报错的根源。你原本选型的otj-pg-embedded是纯本地进程级的嵌入式PostgreSQL实现,不需要依赖Docker,但你当前的依赖和注解配置没有正确启用该实现。
解决方案
- 第一步:调整依赖配置
移除pom.xml或build.gradle中zonky嵌入式数据库相关的依赖,引入opentable的otj-pg-embedded依赖,以Maven为例:
<dependency> <groupId>com.opentable.components</groupId> <artifactId>otj-pg-embedded</artifactId> <version>0.13.4</version> <scope>test</scope> </dependency>
可根据你项目的Spring Boot、PostgreSQL版本选择适配的对应版本。
- 第二步:修改测试类注解
移除@AutoConfigureEmbeddedDatabase注解,添加@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)禁止Spring Boot自动替换测试数据源,同时如果你需要注入Controller层Bean做接口测试,单独使用@DataJpaTest仅会扫描JPA相关组件,不会加载Controller,可替换为@SpringBootTest或者额外添加@WebMvcTest(AuthController.class)注解,调整后参考配置:
@ExtendWith(SpringExtension.class) @FlywayTest @SpringBootTest @ActiveProfiles("test") @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) public class AuthControllerTest { @Autowired private AuthController authController; @Test void contextLoads() { } @Test public void authenticateUserTest() { // 测试逻辑 } }
- 第三步:调整测试配置文件
修改application-test.properties,关闭Hibernate自动建表,避免和Flyway迁移冲突,同时配置嵌入式PostgreSQL的基础参数:
# 关闭Hibernate自动建表,由Flyway负责结构迁移 spring.jpa.generate-ddl=false spring.jpa.hibernate.ddl-auto=none spring.jpa.database=POSTGRESQL spring.flyway.schemas=test spring.flyway.enabled=true spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true # 嵌入式PG基础配置,otj会自动生成随机端口、账号,也可手动固定 embedded.postgresql.database=test embedded.postgresql.username=test embedded.postgresql.password=test
- 第四步:可选手动初始化PG实例(适合复杂定制场景)
如果需要对PostgreSQL实例做自定义配置,可直接在测试类中手动启动PG实例,动态注入数据源参数:
@ExtendWith(SpringExtension.class) @FlywayTest @SpringBootTest @ActiveProfiles("test") @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @TestPropertySource(properties = { "spring.datasource.url=jdbc:postgresql://localhost:${embedded.postgresql.port}/test", "spring.datasource.username=test", "spring.datasource.password=test" }) public class AuthControllerTest { private static final EmbeddedPostgres pg = EmbeddedPostgres.builder() .setPort(54321) .setCredentials("test", "test") .start(); @Autowired private AuthController authController; @AfterAll static void stopPg() throws IOException { pg.close(); } // 测试逻辑不变 }
内容的提问来源于stack exchange,提问作者Mihir
相关产品推荐
相关产品推荐

