Springboot Mybatis-Plus数据库单元测试实战(三种方式)
作者:CuteXiaoKe 发布时间:2024-01-24 19:39:28
单元测试长久以来是热门话题,本文不会讨论需不需要写单测,可以看看参考资料1,我个人认为写好单测应该是每个优秀开发者必备的技能,关于写单测的好处在这里我就不展开讨论了,快速进入本文着重讨论的话题,如何写好数据库单测。
为什么要写数据库单测? 相信大家是不是有这样类似的经历,在写完复杂的sql语句后,自信满满的提测,发现很大一部分Bug都是因为sql语句出现问题了,要么少写逗号,要么漏了字段,悔不当初哇,为啥写完不多测测呢!
没关系!这就教你如何写数据库单测,让你轻松告别数据库相关bug。
1. 数据库样例和环境
我们以用户表为例开启本次教程:
图1.1 用户表ER图
引入mybatis-plus插件后,mapper类如下:
@Mapper
public interface UserMapper extends BaseMapper<UserDO> {
}
整体环境:
spring boot: 1.5.18.RELEASE
mybatis: 3.5.1
mybatis plus:3.4.0(此时最新版本,我们会用到最新版本的特性)
在这里我们直接测试的是mybatis plus提供的一些CRUD,当然这些CRUD一般都不会错,实际项目中我们只需对自定义的SQL进行单元测试即可。
2. 方式一:启动整个环境
这种方式应该是日常环境使用最多的,利用SpringBoot自1.4.0版本开始引入的@SpringBootTest注解可以启动我们单元测试所需要的所有环境,当然,如果你项目中运用了其他分布式服务,他同样也会启动这些服务。单测代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public 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 {
@Autowired
private UserMapper userMapper;
@Test
public 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-8
username: root
password: 123456
4. 方式三:只启动数据库环境+本地数据库
在方式二的基础上,进行如下步骤:
我们去掉
@AutoConfigureTestDatabas
注解,直接启动测试嵌入式数据库即可,在这里我们选用H2内存数据库,首先在pom中引入H2 database maven依赖;然后后在test环境下引入sechema.sql文件,这个文件是用来初始化数据库的,核心是创建表格语句;
最后去掉这个页面以后写法和方式二一样,在这里就不给出
注意: 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
来源:https://blog.csdn.net/u012397189/article/details/109288747
猜你喜欢
- 印刷和网络是不一样的。传统的布局排版并不适于网络,因为传统的印刷布局,几乎只想要什么样的平面效果都能很好的达到,但在网络上设计就很困难,尽管
- 本文研究的主要是pyqt5简介及安装方法介绍的有关内容,具体如下。pyqt5介绍pyqt5是一套Python绑定Digia QT5应用的框架
- 直方图的定义直方图的性质只统计某个灰度级出现的次数,图像的大小不一样的话, 某灰度值的像素出现的次数是不一样的。那如果我们在这基础上除以像素
- 前期准备及前情回顾#对于一维向量用np.arange生成以元组形式输出从0开始的数组([0, 1, 2, 3, 4, 5, 6, 7, 8,
- pop()方法从列表移除并返回最后一个对象或obj。语法以下是pop()方法的语法:list.pop(obj=list[-1])
- 原文:Five quick JavaScript tips真是五个很quick的小提示:1.只在<form>元素上使用submi
- 这几天写代码中遇到的一个常见问题,在Python中如何批量的生成一些变量,如生成变量X1, X2, X3,并在后续的方法中调用,完成赋值、取
- 目录一、为什么要用线程池二、线程池练习演示例子1:使用submit方法演示例子2:使用map方法三、线上数据库测试总结:一、为什么要用线程池
- //-------------------------------------------- // 删除千分点。 //-----------
- 一、Python包python包在开发中十分常见,一般通过导入包含特定功能的python模块包进行使用。当然,也可以自己创建打包模块,然后发
- 如何查看MySQL初始密码问题在安装MySQL过程中,以管理员身份运行cmd后进入MySQL的bin目录,然后输入命令“
- 本文实例讲述了Python中subprocess模块用法。分享给大家供大家参考。具体如下:执行命令:>>> subproc
- 目的: 从数据库读取二进制位图图形数据资料, 透过 ImageMagickObject 组件即时制作缩略图,并显示在网页上 (ge
- 一、安装ROS-OpenCV安装OpenCVsudo apt-get install ros-kinetic-vision-opencv l
- 一.使用DOM生成和读取XML文件 实例一: <?php //Creates XML string and XML document
- 一、开发环境集成开发工具:jupyter notebook 6.5.2集成开发环境:Python 3.10.6第三方库:tensorflow
- 功能1: 爬取西拉ip代理官网上的代理ip环境:python3.8+pycharm库:requests,lxml浏览器:谷歌IP地址:htt
- 在Mac上按照官网教程安装成功tensor flow后,但在程序中导入时,仍然报错,包括但不限于以下两个错误。对于这种错误,原因主要在于Ma
- 这是一家游戏公司,他面试通过后 擅长的机试却没答出来,不过还是被录用了。这道题内容大概这样有条蛇它长度不固定,蛇头朝北顺时针盘旋着,请打印出
- 本文实例讲述了Python编程实现正则删除命令功能。分享给大家供大家参考,具体如下:脚本用途:在DOS下使用del功能箭头,不支持正则表达式