programing

스프링 부트 테스트용 조립식 짐받이

abcjava 2023. 2. 25. 19:30
반응형

스프링 부트 테스트용 조립식 짐받이

데이터베이스 이행을 위해 Flyway를 사용하여 Postgres에서 지원하는 Spring Boot 앱을 구축하고 있습니다.Postgres와 임베디드 유닛 테스트 데이터베이스(Postgres 호환성 모드가 활성화되어 있어도)에서 원하는 결과를 생성할 수 없는 문제에 부딪혀 왔습니다.그래서 유닛 테스트에 임베디드 Postgres를 사용하려고 합니다.

장래성이 있어 보이는 내장 포스트그레스 실장은 있습니다만, Spring Boot의 유닛 테스트 프레임워크(Spring Data 저장소 테스트용) 내에서만 실행되도록 설정하는 방법은 잘 모르겠습니다.상기 툴 또는 대체 임베디드 버전의 Postgres를 사용하여 이를 어떻게 셋업할 수 있습니까?

저는 @MartinVollejnik이 언급한 임베디드 데이터베이스 스프링 테스트 라이브러리의 저자입니다.라이브러리는 고객의 요구를 모두 충족시킬 필요가 있다고 생각합니다(포스트).SQL + Spring Boot + Flyway + 통합 테스트).번거로우시겠지만, Spring Boot 프레임워크와 함께 라이브러리 사용법을 보여주는 간단한 데모 앱을 만들었습니다.아래에 당신이 해야 할 몇 가지 기본적인 단계를 요약했습니다.

메이븐 설정

다음 maven 의존관계를 추가합니다.

<dependency>
    <groupId>io.zonky.test</groupId>
    <artifactId>embedded-database-spring-test</artifactId>
    <version>2.0.1</version>
    <scope>test</scope>
</dependency>

플라이웨이 구성

응용 프로그램 구성에 다음 속성을 추가합니다.

# Sets the schemas managed by Flyway -> change the xxx value to the name of your schema
# flyway.schemas=xxx // for spring boot 1.x.x
spring.flyway.schemas=xxx // for spring boot 2.x.x

또, 반드시, 다음의 것을 사용하지 말아 주세요.org.flywaydb.test.junit.FlywayTestExecutionListener라이브러리에는 데이터베이스 초기화를 최적화할 수 있는 자체 테스트 실행 청취자가 있으며 이 최적화는 다음 경우에 효과가 없습니다.FlywayTestExecutionListener적용됩니다.

임베디드 데이터베이스의 사용을 나타내는 테스트클래스의 예를 다음에 나타냅니다.

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureEmbeddedDatabase
public class SpringDataJpaAnnotationTest {

    @Autowired
    private PersonRepository personRepository;

    @Test
    public void testEmbeddedDatabase() {
        Optional<Person> personOptional = personRepository.findById(1L);

        assertThat(personOptional).hasValueSatisfying(person -> {
            assertThat(person.getId()).isNotNull();
            assertThat(person.getFirstName()).isEqualTo("Dave");
            assertThat(person.getLastName()).isEqualTo("Syer");
        });
    }
}

이 문제에 대한 또 다른 매우 깨끗한 해결책은TestContainers도서관.유일한 경고는 Docker가 필요하다는 것이다.

통합 테스트:

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = {ApplicationTestsIT.Initializer.class})
public class ApplicationTestsIT {

    private static int POSTGRES_PORT = 5432;

    @Autowired
    private FooRepository fooRepository;

    @ClassRule
    public static PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres")
            .withDatabaseName("foo")
            .withUsername("it_user")
            .withPassword("it_pass")
            .withInitScript("sql/init_postgres.sql");

    static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            TestPropertyValues.of(
                    "spring.data.postgres.host=" + postgres.getContainerIpAddress(),
                    "spring.data.postgres.port=" + postgres.getMappedPort(POSTGRES_PORT),
                    "spring.data.postgres.username=" + postgres.getUsername(),
                    "spring.data.postgres.password=" + postgres.getPassword()
            ).applyTo(configurableApplicationContext.getEnvironment());
        }
    }

    @Test
    public void fooRepositoryTestIT() {
        ...
    }

의존관계 설정:
pom.xml:

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

build.gradle:

testCompile "org.testcontainers:postgresql:x.x.x"

링크:
Test Containers - 데이터베이스
테스트 컨테이너 - 포스트그레스 모듈

다음 설정은 Spring Boot 2.0에서 올바르게 동작합니다.

임베디드 데이터베이스 스프링 테스트에 비해 장점은 이 솔루션이 Flyway를 클래스 패스로 밀어넣지 않고 Spring Boot의 자동 구성이 엉망이 될 수 있다는 것입니다.

@Configuration
@Slf4j
public class EmbeddedPostgresConfiguration {

    @Bean(destroyMethod = "stop")
    public PostgresProcess postgresProcess() throws IOException {
        log.info("Starting embedded Postgres");

        String tempDir = System.getProperty("java.io.tmpdir");
        String dataDir = tempDir + "/database_for_tests";
        String binariesDir = System.getProperty("java.io.tmpdir") + "/postgres_binaries";

        PostgresConfig postgresConfig = new PostgresConfig(
                Version.V10_3,
                new AbstractPostgresConfig.Net("localhost", Network.getFreeServerPort()),
                new AbstractPostgresConfig.Storage("database_for_tests", dataDir),
                new AbstractPostgresConfig.Timeout(60_000),
                new AbstractPostgresConfig.Credentials("bob", "ninja")
        );

        PostgresStarter<PostgresExecutable, PostgresProcess> runtime =
                PostgresStarter.getInstance(EmbeddedPostgres.cachedRuntimeConfig(Paths.get(binariesDir)));
        PostgresExecutable exec = runtime.prepare(postgresConfig);
        PostgresProcess process = exec.start();

        return process;
    }

    @Bean(destroyMethod = "close")
    @DependsOn("postgresProcess")
    DataSource dataSource(PostgresProcess postgresProcess) {
        PostgresConfig postgresConfig = postgresProcess.getConfig();

        val config = new HikariConfig();
        config.setUsername(postgresConfig.credentials().username());
        config.setPassword(postgresConfig.credentials().password());
        config.setJdbcUrl("jdbc:postgresql://localhost:" + postgresConfig.net().port() + "/" + postgresConfig.storage().dbName());

        return new HikariDataSource(config);
    }
}

메이븐:

        <dependency>
            <groupId>ru.yandex.qatools.embed</groupId>
            <artifactId>postgresql-embedded</artifactId>
            <version>2.9</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>

이 클래스는 여기서 찾은 코드를 기반으로 합니다.https://github.com/nkoder/postgresql-embedded-example

해서 사용했어요.HikariDatasource(스프링 부트의 디폴트)를 사용하면, 접속 풀링이 올바르게 됩니다.binariesDir ★★★★★★★★★★★★★★★★★」dataDir반복 테스트에서 비용이 많이 드는 추출+initdb를 피하기 위해 사용됩니다.

https://github.com/zonkyio/embedded-database-spring-test 를 참조해 주세요.확실히 하자면, 통합 테스트용입니다.즉, 스프링 컨텍스트는 개별 테스트 중에 초기화됩니다.

툴의 매뉴얼에 따르면 필요한 것은 다음과 같습니다.@AutoConfigureEmbeddedDatabase다음 중 하나:

@RunWith(SpringRunner.class)
@AutoConfigureEmbeddedDatabase
@ContextConfiguration("/path/to/app-config.xml")
public class FlywayMigrationIntegrationTest {

    @Test
    @FlywayTest(locationsForMigrate = "test/db/migration")
    public void testMethod() {
        // method body...
    }
}

Maven 종속성을 추가합니다.

<dependency>
  <groupId>io.zonky.test</groupId>
  <artifactId>embedded-database-spring-test</artifactId>
  <version>1.1.0</version>
  <scope>test</scope>
</dependency>

함께 사용하기 위해서@DataJpaTest합니다.@AutoConfigureTestDatabase(replace = NONE):

@RunWith(SpringRunner.class)
@AutoConfigureTestDatabase(replace = NONE)
@AutoConfigureEmbeddedDatabase
@DataJpaTest
public class SpringDataJpaTest {
// class body...
}

사용하기 쉽게 하기 위해 다음과 같은 복합 주석을 만들 수도 있습니다.

@Documented
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@AutoConfigureTestDatabase(replace = NONE)
@AutoConfigureEmbeddedDatabase
@DataJpaTest
public @interface PostgresDataJpaTest {
}

..그리고 테스트 클래스 위에 사용합니다.

@RunWith(SpringRunner.class)
@PostgresDataJpaTest // custom composite annotation
public class SpringDataJpaTest {
// class body...
}

https://github.com/TouK/dockds 에 접속할 수 있습니다.그러면 도커 포함 데이터베이스가 자동으로 설정됩니다.

언급URL : https://stackoverflow.com/questions/48956743/embedded-postgres-for-spring-boot-tests

반응형