返回

TestContainers JPA 存储库映射端口错误:一个详尽的故障排除指南

java

解决 TestContainers 中 JPA 存储库映射端口错误的详尽指南

引言

在开发过程中,自动化测试是确保代码库健壮性和可靠性的关键。TestContainers 是一款流行的库,它允许你在真实环境中测试你的应用程序,包括数据库连接和网络交互。然而,在对使用 JPA 存储库的 Spring Boot 应用程序进行测试时,你可能会遇到一个恼人的错误:“Mapped port can only be obtained after the container is started”。本文将深入探讨这个问题,并指导你一步步解决它。

错误原因

此错误表示 TestContainers 容器尚未在测试开始时启动。TestContainers 旨在自动启动容器,但在某些情况下,它可能需要明确初始化。

解决方法

步骤 1:检查容器状态

使用 postgreSQLContainer.isRunning() 方法验证容器是否已启动。如果返回 false,则你需要明确初始化容器。

步骤 2:配置 TestContainers 依赖项

确保在 build.gradle 文件中正确配置了 TestContainers 依赖项:

testCompile "org.testcontainers:testcontainers:1.14.1"
testCompile "org.testcontainers:postgresql:1.14.1"

步骤 3:初始化容器

使用 @ClassRule 注解声明 postgreSQLContainer,并创建一个 Initializer 类来将容器连接到 Spring Boot 应用程序:

@ClassRule
public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:latest");

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());
  }
}

步骤 4:检查连接设置

验证 Initializer 类中配置的连接设置是否正确,确保它们与容器公开的 JDBC URL、用户名和密码相匹配。

步骤 5:查看容器日志

在运行测试时,检查容器日志以查找任何错误消息。这将有助于诊断问题并确定容器是否遇到任何问题。

结论

遵循这些步骤可以有效解决“Mapped port can only be obtained after the container is started”错误,并允许你成功运行 TestContainers 测试。

常见问题解答

  1. 为什么需要手动初始化容器?

在某些情况下,TestContainers 可能需要明确初始化才能在测试开始时启动。

  1. 如何配置 TestContainers 的端口映射?

使用 withExposedPorts(port) 方法配置端口映射,其中 port 是要映射的端口号。

  1. 如何访问容器的映射端口?

使用 postgreSQLContainer.getMappedPort(port) 方法访问容器的映射端口,其中 port 是要访问的端口号。

  1. 如何自定义容器的图像?

使用 withImage("image-name:tag") 方法自定义容器的图像。

  1. 如何在测试中创建和删除数据?

使用 EmbeddedDatabaseConnection 类创建和删除数据,该类提供了对嵌入式数据库连接的访问。