Spring Boot集成Embedded PG运行测试用例失败求助
Process [/var/folders/z5/8c_cdt8s7y9b6_mvqs2v7p3m0000gp/T/embedded-pg/PG-0c0585587b40695247cf72650cd42f92/bin/initdb, -A, trust, -U, postgres, -D, /var/folders/z5/8c_cdt8s7y9b6_mvqs2v7p3m0000gp/T/epg3260060667162991560, -E, UTF-8] failed
java.lang.IllegalStateException: Process [/var/folders/z5/8c_cdt8s7y9b6_mvqs2v7p3m0000gp/T/embedded-pg/PG-0c0585587b40695247cf72650cd42f92/bin/initdb, -A, trust, -U, postgres, -D, /var/folders/z5/8c_cdt8s7y9b6_mvqs2v7p3m0000gp/T/epg3260060667162991560, -E, UTF-8] failed
at io.zonky.test.db.postgres.embedded.EmbeddedPostgres.system(EmbeddedPostgres.java:632)
测试用例逻辑无问题,此前可正常运行,测试代码如下:
import com.opentable.db.postgres.embedded.EmbeddedPostgres; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; import java.io.IOException; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) public class EmbeddedPostgresTest { private static EmbeddedPostgres embeddedPostgres; @Autowired private JdbcTemplate jdbcTemplate; @BeforeAll public static void startEmbeddedPostgres() throws IOException { // Start embedded PostgreSQL instance embeddedPostgres = EmbeddedPostgres.builder().start(); System.setProperty("spring.datasource.url", embeddedPostgres.getJdbcUrl("postgres", "postgres")); System.setProperty("spring.datasource.username", "postgres"); System.setProperty("spring.datasource.password", ""); } @AfterAll public static void stopEmbeddedPostgres() throws IOException { // Stop the embedded PostgreSQL instance if (embeddedPostgres != null) { embeddedPostgres.close(); } } @Test public void testDatabaseConnection() { // Test your repository/database interaction jdbcTemplate.execute("CREATE TABLE test(id SERIAL PRIMARY KEY, name VARCHAR(100));"); jdbcTemplate.execute("INSERT INTO test (name) VALUES ('TestName');"); Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM test", Integer.class); assertThat(count).isEqualTo(1); } }
可行解决办法
清理临时文件:报错路径指向系统临时目录中的嵌入式PG缓存文件,大概率是上次测试异常退出导致文件损坏。手动删除
/var/folders/z5/8c_cdt8s7y9b6_mvqs2v7p3m0000gp/T/embedded-pg目录以及所有/var/folders/z5/8c_cdt8s7y9b6_mvqs2v7p3m0000gp/T/epg*开头的临时目录,再重新运行测试。调整依赖版本:当前使用的嵌入式PG依赖(Zonky或OpenTable)可能存在版本兼容问题。尝试升级到最新稳定版,或者回退到之前能正常运行的版本。
检查系统资源与权限:临时目录所在磁盘空间不足,或是当前用户对临时目录无读写权限,会导致
initdb无法创建或写入文件。检查磁盘剩余空间,确保用户拥有临时目录的读写权限。修正数据源配置时机:原代码在
@BeforeAll中用System.setProperty设置数据源,但Spring上下文可能在此之前已初始化数据源,导致配置未生效。改用@DynamicPropertySource动态注入配置,确保Spring能正确获取嵌入式PG的连接信息:修改后的测试类启动逻辑:
@SpringBootTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) public class EmbeddedPostgresTest { private static EmbeddedPostgres embeddedPostgres; @Autowired private JdbcTemplate jdbcTemplate; @BeforeAll public static void startEmbeddedPostgres() throws IOException { embeddedPostgres = EmbeddedPostgres.builder().start(); } @DynamicPropertySource static void configureProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", () -> embeddedPostgres.getJdbcUrl("postgres", "postgres")); registry.add("spring.datasource.username", () -> "postgres"); registry.add("spring.datasource.password", () -> ""); } @AfterAll public static void stopEmbeddedPostgres() throws IOException { if (embeddedPostgres != null) { embeddedPostgres.close(); } } // 测试方法保持不变 }关闭代理/VPN:部分代理或VPN会干扰嵌入式PG的网络连接,导致初始化失败。临时关闭后重试测试。
内容的提问来源于stack exchange,提问作者Pal Patel

