前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java单元测试: MySQL --- H2

Java单元测试: MySQL --- H2

作者头像
十毛
发布2019-03-27 15:19:10
4.9K0
发布2019-03-27 15:19:10
举报
文章被收录于专栏:用户1337634的专栏

H2是一个使用Java实现的内存内存数据库,支持标准的SQL语法,支持大部分的MySQL语法和函数,很适合依赖关系型数据库(比如MySQL, SQL Server, Oracle等)的单元测试。(本文Spring + MySQL作为项目框架)

4步配置(如何使用H2完成单元测试)

maven配置文件及spring配置文件,比如applicationContext.xml

  1. 添加maven依赖
代码语言:javascript
复制
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
    <scope>test</scope>
</dependency>
  1. 业务项目中使用的MySQL数据源配置如下

applicationContext.xml

代码语言:javascript
复制
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306"></property>
    <property name="username" value="root"></property>
    <property name="password" value="123456"></property>
</bean>
  1. 单元测试中H2数据源配置(取代上面的MySQL数据源配置)如下

unit-test.xml

代码语言:javascript
复制
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
</bean>
  1. 初始化H2数据库(db-initial.sql中的SQL语句只会执行一次)

unit-test.xml

代码语言:javascript
复制
<jdbc:initialize-database data-source="ds">
    <jdbc:script location="classpath:db-initial.sql"/>
</jdbc:initialize-database>

db-initial.sql

代码语言:javascript
复制
SET MODE=MySQL;
SET FOREIGN_KEY_CHECKS=0;
CREATE TABLE `t_chat` (
  `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID序列,自增',
  `fquestion` varchar(500) DEFAULT NULL COMMENT '问题',
  `fanswer` varchar(2000) DEFAULT NULL COMMENT '答案',
  `feditState` char(1) DEFAULT NULL COMMENT '0:未编辑,1:已编辑',
  `favailable` smallint(6) DEFAULT '0' COMMENT '审核状态&删除状态(-1:已删除,0:审核中,1:通过,2:退回)',
  `fcreateTime` datetime DEFAULT NULL COMMENT '该问答创建时间',
  `feditTime` datetime DEFAULT NULL COMMENT '更新/编辑时间',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

单元测试用例

配置完成之后,就可以愉快地写依赖数据库的单元测试了。 下面代码以spock作为单元测试框架为例,抛开given/when/then这种语句快,groovy代码和Java代码基本是一致的

代码语言:javascript
复制
@ContextConfiguration("classpath:unit-test.xml")
@Transactional
class CharDaoTest extends Specification {
    @Resource
    private ChatDao chatDao

    def "return empty list when there are no rows in db"() {
        given:
        Map<String, String> params = new HashMap<>()
        when:
        final List<Chat> chats = chatDao.queryAllChatListByCondition(params)
        then:
        chats.size() == 0
    }

    def "return null when query a non-exists chat"() {
        when:
        final Chat chat = chatDao.queryAllChatListById("1")
        then:
        chat == null
    }
}

注意添加注解:Transactional,不然单元测试之间会存在数据错误

常见问题

H2与MySQL的一些常见区别

  • 注释:不支持表级别的Comment
  • 索引:H2中的索引是数据库内唯一,MySQL中的索引是每张表唯一
  • CURRENT_TIMESTAMP: H2不支持记录更新时自动刷新字段时间,也就是不支持语句ON UPDATE CURRENT_TIMESTAMP

H2常见问题及解决办法

  • 不支持的SQL:如果有的MySQL语句H2不支持,就需要根据不同的数据库执行不同的SQL语句。参考MyBatis中的databaseId

ChatMapper.xml

代码语言:javascript
复制
<select id="queryTemplates" resultMap="templateMap" databaseId="h2">xxx</select>
<select id="queryTemplates" resultMap="templateMap" databaseId="mysql">xxx</select>

unit-test.xml

代码语言:javascript
复制
<bean id="vendorProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
        <props>
            <prop key="MySQL">mysql</prop>
            <prop key="H2">h2</prop>
        </props>
    </property>
</bean>
<bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">
    <property name="properties" ref="vendorProperties"/>
</bean>
  • convertinsertonulltozero: H2在插入数据的时候,如果字段限制为NOT NULL,但是插入的值是null,H2会自动转换为对应类型的默认值("", 0等) h2:convertinsertnulltozero
代码语言:javascript
复制
@Component
class TestEnv {
    @PostConstruct
    private static void initEnv() {
        Mode mode = Mode.getInstance("MYSQL")
        mode.convertInsertNullToZero = false
    }
}

其他需求

  • 查看H2内容:如果调试单元测试时,需要查看H2数据库中内容。可以让H2绑定网络端口,并提供服务,添加bean如下
代码语言:javascript
复制
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server"
        factory-method="createWebServer" init-method="start" lazy-init="false">
    <constructor-arg value="-web,-webAllowOthers,-webPort,11111" />
</bean>

然后浏览器打开http://localhost:11111,![]

1521186192_13_w650_h388.png

1521186202_25_w852_h639.png

参考资料

  1. h2 database
  2. databaseIdProvider
  3. 单元测试之使用H2 Database模拟数据库环境

如果对你有一点帮助,麻烦为我点一个赞,如果没有帮助,也非常期待你的反馈

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.06.22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4步配置(如何使用H2完成单元测试)
  • 单元测试用例
  • 常见问题
    • H2与MySQL的一些常见区别
      • H2常见问题及解决办法
      • 其他需求
      • 参考资料
      相关产品与服务
      云数据库 SQL Server
      腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档