单元测试长久以来是热门话题,本文不会讨论需不需要写单测,可以看看参考资料1,我个人认为写好单测应该是每个优秀开发者必备的技能,关于写单测的好处在这里我就不展开讨论了,快速进入本文着重讨论的话题,如何写好数据库单测。

  为什么要写数据库单测? 相信大家是不是有这样类似的经历,在写完复杂的sql语句后,自信满满的提测,发现很大一部分Bug都是因为sql语句出现问题了,要么少写逗号,要么漏了字段,悔不当初哇,为啥写完不多测测呢!

  没关系!这就教你如何写数据库单测,让你轻松告别数据库相关bug。

1. 数据库样例和环境

  我们以用户表为例开启本次教程:

图1.1 用户表ER图

  引入mybatis-plus插件后,mapper类如下:

@Mapper
public interface UserMapper  extends BaseMapper<UserDO> {}

  整体环境:

  1. spring boot: 1.5.18.RELEASE
  2. mybatis: 3.5.1
  3. mybatis plus:3.4.0(此时最新版本,我们会用到最新版本的特性)

  在这里我们直接测试的是mybatis plus提供的一些CRUD,当然这些CRUD一般都不会错,实际项目中我们只需对自定义的SQL进行单元测试即可。

2. 方式一:启动整个环境

  这种方式应该是日常环境使用最多的,利用SpringBoot自1.4.0版本开始引入的@SpringBootTest注解可以启动我们单元测试所需要的所有环境,当然,如果你项目中运用了其他分布式服务,他同样也会启动这些服务。单测代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testCurd() {UserDO userDO = new UserDO();userDO.setId(7777L);userDO.setGmtModified(new Date());userDO.setGmtCreate(new Date());userDO.setRealName("ke");userDO.setUserName("ni");userMapper.insert(userDO);UserDO select = userMapper.selectById(1);System.out.println(select);}
}

@SpringBootTest注解可以设置需要启动加载的类,按需加载

3. 方式二:只启动数据库环境+远程数据库

  在参考资料2中,最新的mybatis-plus发布版本(3.4.0)中引入了test starter,如图:

图3.1 Mybatis-plus3.4.0引入test模块

  模块引入了新的注解@MybatisPlusTest,这个注解可以帮助我们只启动特定特定的模块,直接上单测代码:

@RunWith(SpringRunner.class)
@MybatisPlusTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testCurd() {UserDO userDO = new UserDO();userDO.setId(7777L);userDO.setGmtModified(new Date());userDO.setGmtCreate(new Date());userDO.setRealName("ke");userDO.setUserName("ni");userMapper.insert(userDO);UserDO select = userMapper.selectById(1);System.out.println(select);}
}

  是不是很轻松?不过我们要注意如下几点关键点:

  • @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)的作用是使用自定义的数据源,而非使用自动配置的嵌入式内存数据源
  • 如果你在项目正在使用类似于druid的连接池,在test模块的时候需要在application配置文件里面直接使用jdbc数据源即可,因为@MybatisPlusTest注解不会启动连接池框架,典型的配置文件application.yml如下:
spring:datasource:url: jdbc:mysql://xxx.xxx.1.110:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8username: rootpassword: 123456

4. 方式三:只启动数据库环境+本地数据库

  在方式二的基础上,进行如下步骤:

  1. 我们去掉@AutoConfigureTestDatabas注解,直接启动测试嵌入式数据库即可,在这里我们选用H2内存数据库,首先在pom中引入H2 database maven依赖;
  2. 然后后在test环境下引入sechema.sql文件,这个文件是用来初始化数据库的,核心是创建表格语句;
  3. 最后去掉这个页面以后写法和方式二一样,在这里就不给出

注意: sechema.sql文件要符合嵌入式数据库的语法,在本例中为h2数据库,如果你正在使用mysql数据库,则需要把mysql的数据库语法转换为h2的数据库语法。

5. @MybatisPlusTest注解原理

  如果你之前使用过MyBatis-Spring-Boot-Starter-Test中的@MybatisTest(参考资料3)的话,你会发现@MybatisPlusTest注解原理与之类似,都是限制spring boot的自动配置(参考资料4),只需要加载特定的配置即可。我们来看一下注解源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(MybatisPlusTestContextBootstrapper.class)
@ExtendWith({SpringExtension.class})
@OverrideAutoConfiguration(enabled = false
)
@TypeExcludeFilters({MybatisPlusTypeExcludeFilter.class})
@Transactional
@AutoConfigureCache
@AutoConfigureMybatisPlus
@AutoConfigureTestDatabase
@ImportAutoConfiguration
public @interface MybatisPlusTest {String[] properties() default {};boolean useDefaultFilters() default true;Filter[] includeFilters() default {};Filter[] excludeFilters() default {};@AliasFor(annotation = ImportAutoConfiguration.class,attribute = "exclude")Class<?>[] excludeAutoConfiguration() default {};
}
  • @OverrideAutoConfiguration(enabled = false)是关键,它关闭了自动配置,而一般在spring boot项目中enable是开启的;
  • @AutoConfigureMybatisPlus注解是自定义注解,这个注解定义了加载所有所需的加载类,在spring.factories里面声明了要自动配置的类:
# AutoConfigureMybatis auto-configuration imports
com.baomidou.mybatisplus.test.autoconfigure.AutoConfigureMybatisPlus=\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration
  • @AutoConfigureTestDatabase注解表明使用的是内存数据库而不是真实数据库

  有了这些限制和规定以后,mybatis-plus在测试环境内就可以自动加载所需要的的配置了,这样就去除了非必要资源的加载。

6. 总结

图6.1 三种数据库单测总结

  如果你正在使用mysql数据库,我推荐使用方式二。如果你能解决mysq语法转h2的问题,推荐使用方式三,这样在离线的情况也可以进行单测,不需要连接远程数据库。

PS:如果你有好的工具来完成mysql转换h2的话可以在评论区里面推荐一下,我这边找了好久,包括自定义写转换、一些专业工具等,感觉对navicat导出的语句作转换不是很好好用。

7.参考资料

[1] 你真的需要单元测试吗?
[2] Mybatis-Plus发布版本
[3] MyBatis-Spring-Boot-Starter-Test
[4] SpringBoot四大神器之auto-configuration

Spring boot Mybatis-Plus数据库单测实战(三种方式)相关推荐

  1. Springboot单元测试mysql_Springboot Mybatis-Plus数据库单元测试实战(三种方式)

    单元测试长久以来是热门话题,本文不会讨论需不需要写单测,可以看看参考资料1,我个人认为写好单测应该是每个优秀开发者必备的技能,关于写单测的好处在这里我就不展开讨论了,快速进入本文着重讨论的话题,如何写 ...

  2. Google GMS 送测的三种方式

    Google送测的三种方式: 1.IR:新增出货区域 比如之前报备的是欧盟,现在同型号新增一个出货区域,在俄罗斯,这个要全测,并且收费. 2.SMR:是指已经量产的机器,只更新Google的安全pat ...

  3. mysql数据库删除数据的三种方式:

    mysql数据库删除数据的三种方式: delete from table where 直接删除表中的某一行数据,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作.所以delete相 ...

  4. MyBatis中模糊查询LIKE的三种方式

    在操作数据库时,查询是最常用的语句,模糊查询也是数据库SQL中使用频率很高的SQL语句,利用MyBatis框架来进行更加灵活的模糊查询,有如下三种方式: (1)直接传参法        直接传参法,就 ...

  5. Mybaits plus 数据库映射java实体三种方式

    前言 数据库一般是用下划线进行设计字段,Java实体一般用驼峰法设计属性.这是不成文的规定.当数据库字段映射java实体会出现问题.下面分别是数据库字段和实体属性. 解决问题三种方式 1.利用mysq ...

  6. 3. mysql的注解驱动的三种方式_上手spring boot项目(三)之spring boot整合mybatis进行增删改查的三种方式。...

    1.引入依赖 org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot- ...

  7. 对spring boot yml配置文件敏感信息加密处理的两种方式

    目录 方式一:手动配置加密处理(手动配置分三种情况) 方式二:spring boot整合Jasypt实现yml配置文件敏感信息加密 yml配置文件敏感信息无非就是数据库密码,redis密码,以及整合的 ...

  8. 在Spring Boot中实现通用Auth认证的几种方式

    来源 | https://zhenbianshu.github.io/ 文章介绍了spring-boot中实现通用auth的四种方式,包括 传统AOP.拦截器.参数解析器和过滤器,并提供了对应的实例代 ...

  9. oracle读取数据方式,关于oracle数据库读取数据的三种方式

    打开oracle sqldeveloper,连接到HR模式下的数据库,在SQL工作表中,执行如下语句: CREATE TABLE WANG( Name  varchar2(6), ID     num ...

最新文章

  1. IDEA中根据数据库自动生成实体类,并自定义所生成的实体类中的注解 @Table @Id @...
  2. [20170728]oracle保留字.txt
  3. oracle SQL 命令行(三.增删改查)
  4. XML在JAVA项目中的作用
  5. html画布显示PPT,【Web前端问题】有没有办法让HTML5 canvas显示/预览word/excel/powerpoint 文档?...
  6. 纪中C组模拟赛总结(2019.7.9)
  7. flux react php,Vue的Flux框架之Vuex状态管理器
  8. 黑客编程为什么首选Python语言?这个高速你答案!
  9. 力扣914.卡牌分组
  10. 为什么Java中只有值传递
  11. java统计字符串数字出现次数_java实现统计字符串中大写字母,小写字母及数字出现次数的方法示例...
  12. HighCharts (web 页面的图表框架)
  13. 20200525-生物技术-四川师范大学自考生物技术(本科)考试计划.txt
  14. SCI论文 Introduction 部分没有思路,快来看看这个写作模板
  15. Jenkins Config File Provider 插件 创建kubeconfig文件
  16. Appium 测试APK
  17. 电子邮件格式是什么,你知道电子邮件在哪里找吗
  18. win11电脑所有的浏览器都上不了网怎么解决
  19. 入门学习duilib的要点
  20. z-stac配置按键

热门文章

  1. 互联网公司总部选址分布:后厂村就是半个中国互联网
  2. 绝地求生中的士兵等级
  3. 三轴试验相关理论知识(1)
  4. SSRF盲打 Collaborator everywhere
  5. 最先进的Git分布式仓库系统——是如何提升编程效率的?
  6. vue中如何实现列表的详情页获取及渲染
  7. Spring JDBC 批量操作 数据
  8. mysql的查询分析工具下载_万能数据库查询分析器(ODBC数据库查询分析工具)V7.03 最新版...
  9. 与BB-8跨次元对话,三星Bixby亮相星球大战首映礼
  10. 我是阿圆,我们明年见。