有没有办法在JUnit测试用例中运行MySQL内存?

时间:2011-07-18 14:23:42

标签: java mysql junit

我只是想为访问MySQL数据库的服务添加测试用例,我想重新创建整个模式(对于某些场景,也只是使用带有每个测试用例所需数据的MySQL转储文件)。我环顾四周,发现有些人使用SQLite / H2和其他人来做这件事,但我只是在游荡,如果有任何办法在内存中运行MySQL,所以我不需要担心MySQL的任何特定内容方言我可能会在我们的服务上使用。

7 个答案:

答案 0 :(得分:33)

使用与MySQL完全兼容且可在JUnit测试用例中使用的内存数据库的最简单方法是imho MariaDB4j。 你只需要一个Gradle(/ Maven)依赖项(http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22mariaDB4j%22)和几行代码来启动:

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

可以通过

包含启动脚本
database.source("path/to/resource.sql");

有关GitHub自述文件的更多信息: https://github.com/vorburger/MariaDB4j

编辑: 我在这个答案中添加了一些提示:MariaDB4j似乎在系统临时文件夹中添加了文件。所以它将以嵌入的方式工作,这意味着不需要安装任何东西,你可以通过你想要的构建工具使用依赖。但它不是真正的仅在内存中的解决方案,因此我们不能再谈论单元测试,因为单元测试不能依赖于文件或数据库

答案 1 :(得分:19)

我们使用MySQL和flyway来处理迁移。

对于单元测试和简单集成测试,我们在内存数据库中使用H2和MODE = MySQL参数。 Mode = MySQL使H2 db能够处理大部分MySQL方言。

我们在Spring配置中的测试数据源设置如下:

    <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转换为调用新的BasicDataSource,然后在创建的实例上调用setDriverClassName和setUrl)

然后我们在数据源上使用flyway创建模式,并像对待常规MySQL数据库一样读取:

    <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脚本或使用<jdbc:initialize-database...>标记运行许多MySQL脚本。

答案 2 :(得分:3)

这是使用专有SQL扩展通常不是一个好主意的原因之一。

我要做的是尝试确定使用非标准SQL的位置,并重构代码以将这些部分移动到专用服务。然后你可以在运行单元测试时模拟它们。

答案 3 :(得分:1)

您可以为JUnit测试使用不同的架构。如果您使用的是Spring,那么JUnit扩展允许每个测试在只读事务中运行,因此测试后数据库中不会有任何数据持久存在。如果您需要测试的初始数据,则将所需数据放入参与事务的@Before标记方法中。

答案 4 :(得分:1)

您可以安装ramdrive(使用ImDisk),在其上复制数据文件,并在更改my.cnf中的相应配置后启动Mysql服务 单元测试数据库通常很小(你应该将它们保持在较小的状态以便进行快速测试),它们通常可以放在ramdrive中。

您也可以考虑在春季测试中使用事务,而不是在每次测试时重建表。

我们将它用于我们的开发团队,它就像一个魅力,我们获得了一个数量级的速度。

答案 5 :(得分:1)

我建议使用基于 docker 的 mysql/postgres/DB testcontainer。

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

应用程序-test.yml

  datasource:
    initialization-mode: always
    schema: classpath*:schema-h2.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

答案 6 :(得分:0)

尝试http://hsqldb.org/,我没有经验,但听到了好消息。

修改 抱歉 - 您似乎 需要删除任何MySQL特定语法...