programing

JUnit 테스트 케이스에서 MySQL을 실행하는 방법이 있습니까?

randomtip 2023. 1. 15. 12:48
반응형

JUnit 테스트 케이스에서 MySQL을 실행하는 방법이 있습니까?

MySQL DB에 액세스하는 서비스에 대한 테스트 케이스를 추가하려고 합니다. 스키마 전체를 다시 만들고 싶습니다(또한 시나리오에 따라서는 각 테스트 케이스에 필요한 데이터가 포함된 MySQL 덤프 파일을 사용합니다).주위를 둘러보니 SQLite / H2 등을 사용하는 사람들이 있었습니다만, MySQL을 인메모리에서 실행할 수 있는 방법이 없는지 망설이고 있기 때문에 서비스에 사용할 MySQL 방언에 대해 특별히 걱정할 필요는 없습니다.

MySQL과 완전히 호환되며 JUnit 테스트 케이스 내에서 사용할 수 있는 메모리 데이터베이스에서 를 사용하는 가장 쉬운 방법은 imho MariaDB4j입니다. Gradle(/Maven) 종속성(http://search.maven.org/ #search%7Cga%7C1%7Ca%3A%22mariaDB4j22%)과 몇 줄의 시작만 있으면 됩니다.

DB database = DB.newEmbeddedDB(3306);
database.start();
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", "");

기동 스크립트는, 다음의 방법으로 포함할 수 있습니다.

database.source("path/to/resource.sql");

GitHub readme에 대한 자세한 내용은http://https://github.com/vorburger/MariaDB4j 를 참조해 주세요.

편집: 이 답변에 몇 가지 힌트가 있습니다.MariaDB4j는 시스템 임시 폴더에 파일을 추가하는 것 같습니다.따라서 임베디드 방식으로 작동하므로 아무것도 설치할 필요가 없으며 원하는 빌드 도구를 통해 종속성을 사용할 수 있습니다.그러나 이는 메모리 내 전용 솔루션이 아니기 때문에 유닛 테스트는 파일이나 데이터베이스에 의존해서는 안 되기 때문에 유닛 테스트에 대해서는 더 이상 말할 수 없습니다.

MySQL과 플라이웨이를 사용하여 이행을 처리합니다.

유닛 테스트 및 간단한 통합 테스트에서는 H2 인메모리 데이터베이스와MODE=MySQLPARAM.Mode=MySQLH2 DB가 MySQL 사투리의 대부분을 처리할 수 있도록 합니다.

스프링 구성의 테스트 데이터 소스는 다음과 같이 설정됩니다.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" />
</bean>

(Spring을 모르는 경우 - XML은 호출로 변환됩니다.new BasicDataSource그리고 나서 전화한다.setDriverClassName그리고.setUrl작성된 인스턴스에서)

그런 다음 데이터 소스의 Flyway를 사용하여 스키마를 만들고 일반 MySQL DB에 대해 읽듯이 읽습니다.

<bean id="flyway" class="com.googlecode.flyway.core.Flyway" init-method="migrate">
    <property name="dataSource" ref="dataSource" />
    <property name="cleanOnValidationError" value="false" />
    <property name="initOnMigrate" value="true" />
    <property name="sqlMigrationSuffix" value=".ddl" />
</bean>

jdbcTemplate에서 dataSource bean을 사용하여 일부 SQL 스크립트를 실행하거나 여러 MySQL 스크립트를 실행할 수도 있습니다.<jdbc:initialize-database...>태그를 붙입니다.

이것이 전용 SQL 확장을 사용하는 것이 일반적으로 좋지 않은 이유 중 하나입니다.

비표준 SQL을 사용하는 장소를 특정하고 코드를 수정하여 전용 서비스로 이동합니다.그런 다음 장치 테스트를 실행할 때 이러한 항목을 조롱할 수 있습니다.

도커 기반의 mysql/postgres/DB test container를 사용하는 것이 좋습니다.

Pom.xml

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

XyzIT.java

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
@Testcontainers

Application-test.yml

  datasource:
    initialization-mode: always
    schema: classpath*:schema-anyDb.sql  #initial sql script to createDB
    url: jdbc:tc:postgresql:11.9:///
  jpa:
    hibernate.ddl-auto: none
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
        default_schema: public
    show-sql: true

쥬니트Spring을 사용하는 경우 JUnit 확장 기능을 사용하여 각 테스트를 읽기 전용 트랜잭션으로 실행할 수 있으므로 테스트 후 데이터가 데이터베이스에 영구적이지 않습니다..@Before트랜잭션에 참여하는 표시된 메서드.

my.cnf Unit 테스트 데이터베이스의 적절한 구성을 변경한 후 RAM드라이브(ImDisk를 사용하여)를 마운트하고 데이터 파일을 복사하여 Mysql 서비스를 시작할 수 있습니다(또한 고속 테스트를 위해 RAM드라이브를 작게 유지해야 합니다).

또한 스프링 테스트에서 각 테스트에서 테이블을 재구성하는 대신 트랜잭션을 사용하는 것도 고려할 수 있습니다.

개발팀을 위해 그것을 사용했고, 그것은 마법처럼 작동했고, 우리는 속도 면에서 엄청난 것을 얻었습니다.

언급URL : https://stackoverflow.com/questions/6734410/is-there-a-way-to-run-mysql-in-memory-for-junit-test-cases

반응형