spring-data-jpa Sping Boot TestContainersMap的端口只能在启动容器后获取

vsikbqxv  于 2022-11-10  发布在  Spring
关注(0)|答案(3)|浏览(130)

我正在尝试使用TestContainers库向我的 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

据我所知,容器应该在开始测试时启动,有人知道我遗漏了什么吗?

u1ehiz5o

u1ehiz5o1#

您尝试将PostgresSQLContainer用作JUnit ClassRule,但使用@ExtendWith似乎表明您使用的是不支持JUnit 4规则的JUnit 5 / Jupiter。
请改用JUnit 5集成的测试容器:https://www.testcontainers.org/test_framework_integration/junit_5/

fykwrbwg

fykwrbwg2#

不确定它是否对smdy有帮助,但对我来说,在它的定义解决了问题后启动实际的测试容器:

@Container
private static final PostgreSQLContainer DATABASE = new PostgreSQLContainer("postgres:14");

static {
    DATABASE.start();
}

// any kind of DynamicPropertySources or initializers 
// goes below and can successfully get mapped port from DATABASE.getJdbcUrl()
mw3dktmi

mw3dktmi3#

当我仍然使用Junit 4 org.junit.test来注解测试方法时,这个问题就出现了。在这种情况下,按照Dzmitry的建议添加显式的start命令对我很有效。作为更合适的补救措施,我使用Junit 5 org.junit.jupiter.api.test注解来注解我的测试方法。在这种情况下,容器在没有显式start命令的情况下启动。
以下对我有用
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
public class DataBaseConnectionTest {

    @Container
    private static final PostgreSQLContainer<?> databaseContainer = new PostgreSQLContainer<>("postgres:14");

    ...
    @Test
    void test1() {
    System.out.println(databaseContainer..getJdbcUrl());
    }

}

以下是我的Maven依赖项:

<dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.9.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.9.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>1.17.5</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>testcontainers</artifactId>
        <version>1.17.5</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>postgresql</artifactId>
        <version>1.17.5</version>
        <scope>test</scope>
    </dependency>

相关问题