mysql单元测试

况鸿雪
2023-12-01

embedded-db-junit:JUnit Rule for providing an embedded in-memory database for your tests 

mysql-connector-mxj:MySQL Connector/MXJ is a Java Utility package for deploying and managing a MySQL database.

h2:H2 is an embeddable RDBMS written in Java. 


使用H2做内存数据库进行MySQL单元测试,也是有不尽人意的地方:

http://matthewcasperson.blogspot.com/2013/07/exporting-from-mysql-to-h2.html
1.mysql单引号用'\'转义,H2用 ''两个单引号转义
2.msyql十六进制导入H2失败(这个没试验出来,没搞懂应用场景)
3.mysql一位default值是b'0',H2用0
4.H2 key键设置不能使用范围,例如: KEY "ATextFieldKey" ("ATextField"(255))
5.清除mysql脚本中的character字符集设置
6.清除mysql脚本中的COLLATE字段设置
7.清除mysql脚本中BLOBS,CLOBS和TEXT字段上的索引
8.H2要保证整个database的索引名字唯一
9.对于外键,H2要求关联的表在key创建前已经存在
10.mysql的字段类型enum、json在H2里面不支持
11.还有未发现待补充。。。

目前致力于寻求解决方案:

http://h2database.com/html/links.html#tools
https://github.com/bgranvea/mysql2h2-converter

 


H2使用步骤:

test-tools项目已经封装了H2的依赖和默认设置,故只需引入pom即可

<dependency>
 <groupId>com.xueqiu.infra</groupId>
 <artifactId>test-tools</artifactId>
 <version>1.0.3</version>
</dependency>

version版本根据实时情况更新

H2使用示例:

只需指定schema和data的sql脚本文件地址,通过list形式传入即可,详情见如下示例地址

示例地址:

源码版:http://git.snowballfinance.com/lib/test-tools

/**
 * h2 replace mysql unit test
 *
 * 使用H2代替mysqld进行单元测试,注意会出现SQL脚本的语法兼容问题
 */
@Test
public void testH2(){
    TestEnvironment env = new TestEnvironmentBuilder()
            .withH2Database(Arrays.asList("h2/demo_schema.sql", "h2/demo_data.sql"))
            .build();
 try {
        QueryRunner queryRunner = new QueryRunner();
 Connection conn = TestEnvironment.jdbcDataSource().get().getConnection();
 String query = "select * from test.t_demo";
 List<Map<String, Object>> listOfMaps = queryRunner.query(conn, query, new MapListHandler());
 System.out.println(listOfMaps);
 Assert.assertEquals(listOfMaps.size(), 2);
 } catch (SQLException se) {
        Assert.assertTrue(false);
 throw new RuntimeException("Couldn't query the h2.", se);
 }
}

示例地址:

spring版:http://git.snowballfinance.com/hekuangsheng/xueqiu-push

test的resource目录下添加sql文件
src
  --main
    --test
      --java
        --包路径
          --TestConfig.java
          --BaseTests.java
          --H2DatasourceTest.java
      --resources
        --sql
          --demo_schema.sql
          --demo_data.sql

demo_schema.sql

DROP SCHEMA IF EXISTS `test`;
CREATE SCHEMA `test`;
DROP TABLE IF EXISTS `test`.`t_demo`;
CREATE TABLE `test`.`t_demo` (
  `id` BIGINT (20) NOT NULL DEFAULT '0' COMMENT '主键',
  `demo_key`  VARCHAR(255)      NOT NULL DEFAULT '0' COMMENT '',
  `demo_value`  VARCHAR (255) NOT NULL DEFAULT '0' COMMENT '',
  PRIMARY KEY (`id`)
);

demo_data.sql

insert into `test`.t_demo(id, demo_key, demo_value) values (1, 'key','value');
insert into `test`.t_demo(id, demo_key, demo_value) values (2, 'key2','value2');

TestConfig.java

import com.xueqiu.infra.test.tools.TestEnvironment;
import com.xueqiu.infra.test.tools.TestEnvironmentBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.List;


@ComponentScan(
        basePackages = {
                "com.xueqiu.infra.push.server.entity",
        },
        excludeFilters = {
                @ComponentScan.Filter(Controller.class)
        }
)
@Configuration
public class TestConfig {

    private TestEnvironment env = new TestEnvironmentBuilder()
            .withH2Database(Arrays.asList("sql/demo_schema.sql", "sql/demo_data.sql"))
            .build();

    @Bean(name = {"dataSource", "userDataSource", "snowballDataSource", "recommendBaseDataSource"})
    public DataSource dataSource() {
        return TestEnvironment.jdbcDataSource()
                .orElseThrow(() -> new RuntimeException("init test data source fail"));
    }

    @Bean(name = "xueqiupushTemplate")
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager tm = new DataSourceTransactionManager();
        tm.setDataSource(dataSource);
        return tm;
    }

}

BaseTests.java

import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

@Ignore
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@TestExecutionListeners(TransactionalTestExecutionListener.class)
@Transactional
public class BaseTests extends AbstractJUnit4SpringContextTests {

}

H2DatasourceTest.java

import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;

public class H2DatasourceTest extends BaseTests {

    @Autowired
    private JdbcTemplate xueqiupushTemplate;

    @Test
    public void initToken_test() {
        String query = "select * from test.t_demo";
        List<Map<String, Object>> result = xueqiupushTemplate.queryForList(query);
        Assert.assertEquals(result.size(),2);
    }
}

 

 类似资料: